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

cucumber.runtime.arquillian.feature.Features Maven / Gradle / Ivy

There is a newer version: 1.6.7
Show newest version
package cucumber.runtime.arquillian.feature;

import cucumber.api.junit.Cucumber;
import cucumber.runtime.io.FileResource;
import cucumber.runtime.io.MultiLoader;
import cucumber.runtime.io.Resource;
import cucumber.runtime.io.ZipResource;

import java.io.File;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Logger;

import static cucumber.runtime.arquillian.shared.ClassLoaders.load;

public final class Features {
    private static final Logger LOGGER = Logger.getLogger(Features.class.getName());

    public static final String EXTENSION = ".feature";

    private Features() {
        // no-op
    }

    public static String featurePath(final Class javaClass) {
        return javaClass.getPackage().getName().replace('.', '/')
                + '/' + createClassNameSubPackage(javaClass.getSimpleName()) + EXTENSION;
    }

    public static Map> createFeatureMap(final String featureHome, final Class javaClass, final ClassLoader loader) {
        final Map> featureUrls = new HashMap>();

        final String home;
        if (featureHome != null && !featureHome.endsWith("/")) {
            home = featureHome + "/";
        } else {
            home = featureHome;
        }

        final boolean client = isClient();

        for (final String path : findFeatures(javaClass)) {
            final Collection list = new ArrayList();

            final boolean directResource = path.endsWith(".feature");

            if (directResource) {
                { // from classpath
                    final URL url = loader.getResource(path);
                    if (url != null) {
                        list.add(url);
                        featureUrls.put(path, list);
                        continue;
                    }
                }

                // from filesystem
                if (urlFromFileSystem(featureUrls, list, path, path)) {
                    continue;
                }

                // from filesystem with featureHome
                if (home != null && urlFromFileSystem(featureUrls, list, path, featureHome + path)) {
                    continue;
                }
            }

            if (client) { // scan on client side to avoid URL issues in the server
                findWithCucumberSearcher(loader, path, list);
                if (home != null) {
                    findWithCucumberSearcher(loader, home + path, list);
                }
                if (!list.isEmpty()) {
                    featureUrls.put(path, list);
                }
            } // else already done on client side
        }

        return featureUrls;
    }

    private static boolean urlFromFileSystem(final Map> featureUrls, final Collection list, final String path, final String filePath) {
        final File file = new File(filePath);
        if (file.exists() && !file.isDirectory()) {
            try {
                list.add(file.toURI().toURL());
                featureUrls.put(path, list);
                return true;
            } catch (final MalformedURLException e) {
                // no-op
            }
        }
        return false;
    }

    private static void findWithCucumberSearcher(ClassLoader loader, String path, Collection list) {
        final MultiLoader multiLoader = new MultiLoader(loader);
        final Iterator resources;
        try {
            resources = multiLoader.resources(path, EXTENSION).iterator();
        } catch (final IllegalArgumentException iae) { // not a directory...
            return;
        }

        while (resources.hasNext()) {
            final Resource resource = resources.next();

            if (FileResource.class.isInstance(resource)) {
                final FileResource fr = FileResource.class.cast(resource);
                try {
                    final Field field = FileResource.class.getDeclaredField("file");
                    field.setAccessible(true);
                    list.add(File.class.cast(field.get(fr)).toURI().toURL());
                } catch (final Exception e) {
                    // no-op
                }
            } else if (ZipResource.class.isInstance(resource)) {
                list.add(loader.getResource(resource.getPath()));
            } else {
                LOGGER.warning("Resource " + resource + " ignored (unknown type).");
            }
        }
    }

    private static boolean isClient() {
        try {
            load("cucumber.runtime.arquillian.locator.JarLocation");
            return true;
        } catch (final Exception e) {
            return false;
        }
    }

    private static void listFeatures(final Collection list, final File f) {
        final File[] children = f.listFiles();
        if (children != null) {
            for (final File c : children) {
                if (c.exists()) {
                    try {
                        list.add(c.toURI().toURL());
                    } catch (final MalformedURLException e) {
                        // no-op
                    }
                }
            }
        }
    }

    public static Collection findFeatures(final Class javaClass) {
        final Collection featureUrls = new ArrayList();

        { // convention
            final String featurePath = Features.featurePath(javaClass);
            featureUrls.add(featurePath);
        }

        { // our API
            final cucumber.runtime.arquillian.api.Features additionalFeaturesAnn = javaClass.getAnnotation(cucumber.runtime.arquillian.api.Features.class);
            if (additionalFeaturesAnn != null) {
                Collections.addAll(featureUrls, additionalFeaturesAnn.value());
            }
        }

        { // cucumber-junit API
            final Cucumber.Options annotation = javaClass.getAnnotation(Cucumber.Options.class);
            if (annotation != null && annotation.features() != null) {
                Collections.addAll(featureUrls, annotation.features());
            }
        }

        return featureUrls;
    }

    private static String createClassNameSubPackage(final String name) {
        String result = name;
        if (result.endsWith("Test")) {
            result = result.substring(0, result.length() - "Test".length());
        } else if (result.endsWith("IT")) {
            result = result.substring(0, result.length() - "IT".length());
        }

        if (result.length() == 1) {
            return result;
        }

        return Character.toLowerCase(result.charAt(0)) + replaceUpperCaseWithADashAndLowercase(result.substring(1));
    }

    private static String replaceUpperCaseWithADashAndLowercase(final String substring) {
        final StringBuilder builder = new StringBuilder();
        for (final char c : substring.toCharArray()) {
            if (!Character.isUpperCase(c)) {
                builder.append(c);
            } else {
                builder.append('-').append(Character.toLowerCase(c));
            }
        }

        final String s = builder.toString();
        if (s.endsWith("-")) {
            return s.substring(0, s.length() - 1);
        }
        return s;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy