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

com.github.rmannibucau.rules.api.systemproperty.PlaceHoldableSystemProperties Maven / Gradle / Ivy

The newest version!
package com.github.rmannibucau.rules.api.systemproperty;

import org.apache.commons.lang3.text.StrLookup;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import static org.apache.commons.lang3.text.StrLookup.mapLookup;

public class PlaceHoldableSystemProperties implements TestRule {
    private final Object instance;

    public PlaceHoldableSystemProperties() {
        this(null);
    }

    public PlaceHoldableSystemProperties(final Object instance) {
        this.instance = instance;
    }

    @Override
    public Statement apply(final Statement base, final Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                if (description.getAnnotation(SystemProperties.class) == null
                        && description.getTestClass().getAnnotation(SystemProperties.class) == null) {
                    base.evaluate();
                    return;
                }

                final Properties original = new Properties();
                final Properties systProps = System.getProperties();
                original.clear();
                original.putAll(systProps);

                final StrSubstitutor replacer1 = new StrSubstitutor(new DynamicStrLookup());
                final StrSubstitutor replacer2 = new StrSubstitutor(mapLookup(buildFromFields(instance)), "#{", "}", '\\');

                populateProperties(replacer1, replacer2, description.getAnnotation(SystemProperties.class));
                populateProperties(replacer1, replacer2, description.getTestClass().getAnnotation(SystemProperties.class));

                try {
                    base.evaluate();
                } finally {
                    final Properties sp = System.getProperties();
                    sp.clear();
                    sp.putAll(original);
                }
            }
        };
    }

    private void populateProperties(final StrSubstitutor propReplacer, final StrSubstitutor fieldReplacer,
                                    final SystemProperties annotation) {
        if (annotation == null) {
            return;
        }

        final Properties systProps = System.getProperties();
        for (final SystemProperty sp : annotation.value()) {
            systProps.put(sp.key(), fieldReplacer.replace(propReplacer.replace(sp.value())));
        }
        for (final String file : annotation.files()) {
            final Properties p = new Properties();

            final File f = new File(file);
            if (!f.isFile()) {
                final InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(file);
                if (is != null) {
                    try {
                        systProps.load(is);
                    } catch (IOException e) {
                        throw new IllegalStateException(e);
                    } finally {
                        try {
                            is.close();
                        } catch (final IOException e) {
                            // no-op
                        }
                    }
                }
                throw new IllegalArgumentException(file + " doesn't exist");
            } else {
                FileInputStream stream = null;
                try {
                    stream = new FileInputStream(file);
                    p.load(stream);
                } catch (final IOException e) {
                    throw new IllegalStateException(e);
                } finally {
                    if (stream != null) {
                        try {
                            stream.close();
                        } catch (final IOException e) {
                            // no-op
                        }
                    }
                }
            }

            // filter them
            for (final String key : p.stringPropertyNames()) {
                p.put(key, fieldReplacer.replace(propReplacer.replace(p.getProperty(key))));
            }

            systProps.putAll(p);
        }
    }

    private static Map buildFromFields(final Object instance) {
        if (instance == null) {
            return Collections.emptyMap();
        }
        Class current = instance.getClass();
        final Map values = new HashMap();
        while (current != Object.class && !current.isInterface()) {
            for (final Field f : current.getDeclaredFields()) {
                try {
                    f.setAccessible(true);
                    values.put(f.getName(), f.get(instance));
                } catch (final Throwable e) {
                    // no-op
                }
            }
            current = current.getSuperclass();
        }
        return values;
    }

    // by default system properties are cached so if we add one it is ignored
    private static class DynamicStrLookup extends StrLookup {
        @Override
        public String lookup(final String key) {
            return System.getProperty(key);
        }
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy