org.packagesettings.PackageLevelSettings Maven / Gradle / Ivy
package org.packagesettings;
import com.spun.util.ObjectUtils;
import com.spun.util.ThreadUtils;
import org.lambda.functions.Function0;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class PackageLevelSettings
{
public static String PACKAGE_SETTINGS = "PackageSettings";
public static Map get()
{
return getForStackTrace(ThreadUtils.getStackTrace());
}
public static Map getForStackTrace(StackTraceElement[] trace)
{
Map settings = new HashMap();
try
{
HashSet done = new HashSet();
for (StackTraceElement element : trace)
{
String packageName = getNextLevel(element.getClassName());
settings.putAll(getSettingsFor(packageName, done));
}
}
catch (Throwable t)
{
throw ObjectUtils.throwAsError(t);
}
return settings;
}
private static Map getSettingsFor(String packageName, HashSet done)
{
if (packageName == null || done.contains(packageName))
{ return Collections.emptyMap(); }
Map settings = new HashMap();
settings.putAll(getSettingsFor(getNextLevel(packageName), done));
try
{
Class> clazz = loadClass(packageName + "." + PACKAGE_SETTINGS);
Field[] declaredFields = clazz.getDeclaredFields();
Object o = clazz.newInstance();
for (Field field : declaredFields)
{
if (Modifier.isStatic(field.getModifiers()))
{
settings.put(field.getName(), getFieldValue(field, null));
}
else
{
settings.put(field.getName(), getFieldValue(field, o));
}
}
}
catch (Throwable e)
{
//Ignore
}
done.add(packageName);
return settings;
}
private static Settings getFieldValue(Field field, Object from)
{
try
{
field.setAccessible(true);
return new Settings(field.get(from), field.getDeclaringClass().getName());
}
catch (Throwable t)
{
//ignore
}
return null;
}
public static String getNextLevel(String className)
{
int last = className.lastIndexOf(".");
return (last < 0) ? null : className.substring(0, last);
}
public static Class> loadClass(String className)
{
return ObjectUtils
.throwAsError(() -> Class.forName(className, true, Thread.currentThread().getContextClassLoader()));
}
public static Object getValueFor(String key)
{
Settings settings = get().get(key);
return settings == null ? null : settings.getValue();
}
public static T getValueFor(org.packagesettings.Field field)
{
return getValueFor(field, () -> null);
}
public static T getValueFor(org.packagesettings.Field field, Function0 defaultSupplier)
{
return field.getValue(get(), defaultSupplier);
}
}