1616 */
1717package com .optimizely .ab .config .parser ;
1818
19+ import com .optimizely .ab .internal .PropertyUtils ;
1920import org .slf4j .Logger ;
2021import org .slf4j .LoggerFactory ;
2122
2223import javax .annotation .Nonnull ;
24+ import java .util .function .Supplier ;
2325
2426/**
2527 * Factory for generating {@link ConfigParser} instances, based on the json parser available on the classpath.
@@ -37,6 +39,33 @@ public static ConfigParser getInstance() {
3739
3840 //======== Helper methods ========//
3941
42+ public enum ConfigParserSupplier {
43+ GSON_CONFIG_PARSER ("com.google.gson.Gson" , GsonConfigParser ::new ),
44+ JACKSON_CONFIG_PARSER ("com.fasterxml.jackson.databind.ObjectMapper" , JacksonConfigParser ::new ),
45+ JSON_CONFIG_PARSER ("org.json.JSONObject" , JsonConfigParser ::new ),
46+ JSON_SIMPLE_CONFIG_PARSER ("org.json.simple.JSONObject" , JsonSimpleConfigParser ::new );
47+
48+ private final String className ;
49+ private final Supplier <ConfigParser > supplier ;
50+
51+ ConfigParserSupplier (String className , Supplier <ConfigParser > supplier ) {
52+ this .className = className ;
53+ this .supplier = supplier ;
54+ }
55+
56+ ConfigParser get () {
57+ return supplier .get ();
58+ }
59+
60+ private boolean isPresent () {
61+ try {
62+ Class .forName (className );
63+ return true ;
64+ } catch (ClassNotFoundException e ) {
65+ return false ;
66+ }
67+ }
68+ }
4069 /**
4170 * Creates and returns a {@link ConfigParser} using a json parser available on the classpath.
4271 *
@@ -45,35 +74,39 @@ public static ConfigParser getInstance() {
4574 */
4675 private static @ Nonnull
4776 ConfigParser create () {
48- ConfigParser configParser ;
49-
50- if (isPresent ("com.fasterxml.jackson.databind.ObjectMapper" )) {
51- configParser = new JacksonConfigParser ();
52- } else if (isPresent ("com.google.gson.Gson" )) {
53- configParser = new GsonConfigParser ();
54- } else if (isPresent ("org.json.simple.JSONObject" )) {
55- configParser = new JsonSimpleConfigParser ();
56- } else if (isPresent ("org.json.JSONObject" )) {
57- configParser = new JsonConfigParser ();
58- } else {
59- throw new MissingJsonParserException ("unable to locate a JSON parser. "
60- + "Please see <link> for more information" );
77+
78+ String configParserName = PropertyUtils .get ("default_parser" );
79+
80+ if (configParserName != null ) {
81+ try {
82+ ConfigParserSupplier supplier = ConfigParserSupplier .valueOf (configParserName );
83+ if (supplier .isPresent ()) {
84+ ConfigParser configParser = supplier .get ();
85+ logger .debug ("using json parser: {}, based on override config" , configParser .getClass ().getSimpleName ());
86+ return configParser ;
87+ }
88+
89+ logger .warn ("configured parser {} is not available in the classpath" , configParserName );
90+ } catch (IllegalArgumentException e ) {
91+ logger .warn ("configured parser {} is not a valid value" , configParserName );
92+ }
6193 }
6294
63- logger .info ("using json parser: {}" , configParser .getClass ().getSimpleName ());
64- return configParser ;
65- }
95+ for (ConfigParserSupplier supplier : ConfigParserSupplier .values ()) {
96+ if (!supplier .isPresent ()) {
97+ continue ;
98+ }
6699
67- private static boolean isPresent (@ Nonnull String className ) {
68- try {
69- Class .forName (className );
70- return true ;
71- } catch (ClassNotFoundException e ) {
72- return false ;
100+ ConfigParser configParser = supplier .get ();
101+ logger .info ("using json parser: {}" , configParser .getClass ().getSimpleName ());
102+ return configParser ;
73103 }
104+
105+ throw new MissingJsonParserException ("unable to locate a JSON parser. "
106+ + "Please see <link> for more information" );
74107 }
75108
76- //======== Lazy-init Holder ========//
109+ //======== Lazy-init Holder ========//
77110
78111 private static class LazyHolder {
79112 private static final ConfigParser INSTANCE = create ();
0 commit comments