3737 */
3838public interface ApplicationEnvironment {
3939
40+ public static class Resolver {
41+ private static ApplicationEnvironment loaded = null ;
42+
43+ private Resolver () {
44+ // static singleton
45+ }
46+
47+ /**
48+ * @return The selected {@link ApplicationEnvironment}. The selection is made using the following criteria:
49+ * <ol>
50+ * <li>If the {@link #ENV_CLASS} system property or environment variable is set, the class is used</li>
51+ * <li>The {@link ServiceLoader} is used to load all {@link ApplicationEnvironment} instances, which are filtered
52+ * based on {@link #isAvailable()} and then sorted based on {@link #getPriority()} where higher numbers are chosen
53+ * first.</li>
54+ * </ol>
55+ */
56+ public static ApplicationEnvironment load () {
57+ if (loaded != null )
58+ return loaded ;
59+
60+ // First check explicilty configured environment via system property or env var
61+ String strategy = System .getProperty (ENV_CLASS );
62+ if (strategy == null || strategy .isEmpty ())
63+ strategy = System .getenv (ENV_CLASS );
64+ if (strategy != null && !strategy .isEmpty ()) {
65+ Class <?> found ;
66+ try {
67+ found = Class .forName (strategy );
68+ } catch (ClassNotFoundException e ) {
69+ throw new IllegalStateException ("Unable to load the selected ApplicationEnvironment class: " + strategy , e );
70+ }
71+ if (!ApplicationEnvironment .class .isAssignableFrom (found )) {
72+ throw new IllegalStateException ("ApplicationEnvironment class " + strategy +
73+ " was found, but it does not implement the required interface " + ApplicationEnvironment .class );
74+ } else {
75+ try {
76+ loaded = (ApplicationEnvironment ) found .newInstance ();
77+ return loaded ;
78+ } catch (InstantiationException | IllegalAccessException e ) {
79+ throw new IllegalStateException ("Unable to initialize " + found , e );
80+ }
81+ }
82+ }
83+
84+ Logger LOG = LoggerFactory .getLogger (ApplicationEnvironment .class );
85+
86+ // If nothing explicitly defined in sysprops or env, check ServiceLoader
87+ Set <ApplicationEnvironment > envs = new HashSet <>();
88+ ServiceLoader .load (ApplicationEnvironment .class ).forEach (envs ::add );
89+ Optional <ApplicationEnvironment > selectedEnv = envs .stream ()
90+ .map (env -> {
91+ if (LOG .isDebugEnabled ())
92+ LOG .debug ("Found ApplicationEnvironment " + env .getClass () + " with priority=" + env .getPriority () + ", available=" + env .isAvailable ());
93+ return env ;
94+ })
95+ .filter (env -> env .isAvailable ())
96+ .sorted ((c1 , c2 ) -> c1 .getClass ().getCanonicalName ().compareTo (c2 .getClass ().getCanonicalName ()))
97+ .sorted ((c1 , c2 ) -> Integer .compare (c2 .getPriority (), c1 .getPriority ()))
98+ .findFirst ();
99+ loaded = selectedEnv .orElseThrow (() -> new IllegalStateException ("No available " + ApplicationEnvironment .class .getSimpleName () + " was discovered." ));
100+ return loaded ;
101+ }
102+
103+ /**
104+ * @param clazz The {@link ApplicationEnvironment} class to check is active
105+ * @return True if the provided {@link ApplicationEnvironment} is currently active, false otherwise
106+ */
107+ public static boolean isSelected (Class <? extends ApplicationEnvironment > clazz ) {
108+ return load ().getClass ().getCanonicalName ().equals (clazz .getCanonicalName ());
109+ }
110+ }
111+
40112 /**
41113 * The default priority returned by an implementation of {@link ApplicationEnvironment#isAvailable}
42114 * In general, built-in ApplicationEnvironment implementations have a priority less than the default
@@ -47,69 +119,10 @@ public interface ApplicationEnvironment {
47119 /**
48120 * The name of the system property or environment variable that indicates a specific {@link ApplicationEnvironment}
49121 * to use. If this property is set, it will be used regardless of the priority or availability. If this property is
50- * NOT set, the normal resolution rules will be applied as defined in {@link #load()}
122+ * NOT set, the normal resolution rules will be applied as defined in {@link ApplicationEnvironment.Resolver #load()}
51123 */
52124 public static final String ENV_CLASS = "MICROSHED_TEST_ENV_CLASS" ;
53125
54- /**
55- * @return The selected {@link ApplicationEnvironment}. The selection is made using the following criteria:
56- * <ol>
57- * <li>If the {@link #ENV_CLASS} system property or environment variable is set, the class is used</li>
58- * <li>The {@link ServiceLoader} is used to load all {@link ApplicationEnvironment} instances, which are filtered
59- * based on {@link #isAvailable()} and then sorted based on {@link #getPriority()} where higher numbers are chosen
60- * first.</li>
61- * </ol>
62- */
63- public static ApplicationEnvironment load () {
64- // First check explicilty configured environment via system property or env var
65- String strategy = System .getProperty (ENV_CLASS );
66- if (strategy == null || strategy .isEmpty ())
67- strategy = System .getenv (ENV_CLASS );
68- if (strategy != null && !strategy .isEmpty ()) {
69- Class <?> found ;
70- try {
71- found = Class .forName (strategy );
72- } catch (ClassNotFoundException e ) {
73- throw new IllegalStateException ("Unable to load the selected ApplicationEnvironment class: " + strategy , e );
74- }
75- if (!ApplicationEnvironment .class .isAssignableFrom (found )) {
76- throw new IllegalStateException ("ApplicationEnvironment class " + strategy +
77- " was found, but it does not implement the required interface " + ApplicationEnvironment .class );
78- } else {
79- try {
80- return (ApplicationEnvironment ) found .newInstance ();
81- } catch (InstantiationException | IllegalAccessException e ) {
82- throw new IllegalStateException ("Unable to initialize " + found , e );
83- }
84- }
85- }
86-
87- Logger LOG = LoggerFactory .getLogger (ApplicationEnvironment .class );
88-
89- // If nothing explicitly defined in sysprops or env, check ServiceLoader
90- Set <ApplicationEnvironment > envs = new HashSet <>();
91- ServiceLoader .load (ApplicationEnvironment .class ).forEach (envs ::add );
92- Optional <ApplicationEnvironment > selectedEnv = envs .stream ()
93- .map (env -> {
94- if (LOG .isDebugEnabled ())
95- LOG .debug ("Found ApplicationEnvironment " + env .getClass () + " with priority=" + env .getPriority () + ", available=" + env .isAvailable ());
96- return env ;
97- })
98- .filter (env -> env .isAvailable ())
99- .sorted ((c1 , c2 ) -> c1 .getClass ().getCanonicalName ().compareTo (c2 .getClass ().getCanonicalName ()))
100- .sorted ((c1 , c2 ) -> Integer .compare (c2 .getPriority (), c1 .getPriority ()))
101- .findFirst ();
102- return selectedEnv .orElseThrow (() -> new IllegalStateException ("No available " + ApplicationEnvironment .class .getSimpleName () + " was discovered." ));
103- }
104-
105- /**
106- * @param clazz The {@link ApplicationEnvironment} class to check is active
107- * @return True if the provided {@link ApplicationEnvironment} is currently active, false otherwise
108- */
109- public static boolean isSelected (Class <? extends ApplicationEnvironment > clazz ) {
110- return load ().getClass ().equals (clazz );
111- }
112-
113126 /**
114127 * @return true if the ApplicationEnvironment is currently available
115128 * false otherwise
0 commit comments