package org.packagesettings; 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; import com.spun.util.ThreadUtils; public class PackageLevelSettings { public static Map<String, Settings> get() { return getForStackTrace(ThreadUtils.getStackTrace()); } public static Map<String, Settings> getForStackTrace(StackTraceElement[] trace) throws Error { Map<String, Settings> settings = new HashMap<String, Settings>(); try { HashSet<String> done = new HashSet<String>(); for (StackTraceElement element : trace) { String packageName = getNextLevel(element.getClassName()); settings.putAll(getSettingsFor(packageName, done)); } } catch (Throwable t) { throw throwAsError(t); } return settings; } private static Map<String, Settings> getSettingsFor(String packageName, HashSet<String> done) { if (packageName == null || done.contains(packageName)) { return Collections.emptyMap(); } Map<String, Settings> settings = new HashMap<String, Settings>(); settings.putAll(getSettingsFor(getNextLevel(packageName), done)); try { Class<?> clazz = loadClass(packageName + ".PackageSettings"); Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { if (Modifier.isStatic(field.getModifiers())) { settings.put(field.getName(), getFieldValue(field)); } } } catch (ClassNotFoundException e) { //Ignore } done.add(packageName); return settings; } private static Settings getFieldValue(Field field) { try { return new Settings(field.get(null), 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) throws ClassNotFoundException { return Class.forName(className, true, Thread.currentThread().getContextClassLoader()); } public static Error throwAsError(Throwable t) throws Error { if (t instanceof RuntimeException) { throw (RuntimeException) t; } else if (t instanceof Error) { throw (Error) t; } else { throw new Error(t); } } }