package org.commons.jconfig.internal; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.Charset; import java.util.Map.Entry; import javax.annotation.Nonnull; import org.apache.log4j.Logger; import org.commons.jconfig.config.ConfigException; import org.commons.jconfig.config.ConfigManagerConfig; import org.commons.jconfig.config.ConfigRuntimeException; import com.google.gson.JsonElement; import com.google.gson.JsonIOException; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; /** * Encapsulation for parsing and saving Json config. The config values will be * saved to instance variable keyMap * * Structure of keyMap after parsing: { FARM1 : { a:b, d:e }, FARM2 : {f:d, z:y * }, _Defs_ : {a:x} } * * @author lafa * @author jaikit * */ public class ConfigAdapterJson implements ConfigAdapter<String> { private final Logger logger = Logger.getLogger(ConfigAdapterJson.class); private InputStream getStream(final String uri, final Charset charset, final ConfigManagerConfig internalConfig) { logger.info("config uri: " + uri); File dir = new File(internalConfig.getConfigPath()); if (dir.isDirectory()) { File config = new File(dir.getAbsolutePath() + File.separator + uri); if (config.isFile() && config.canRead()) { try { return new FileInputStream(config); } catch (FileNotFoundException e) { logger.warn("File not found: '" + config.getAbsolutePath() + "'"); } } else { logger.warn("Failed to load configuration for resource '" + config.getAbsolutePath() + "'"); } } else { if (logger.isTraceEnabled()) logger.trace("File not found: '" + dir.getAbsolutePath() + File.separator + uri + "'"); } // trying classpath InputStream in = getClass().getResourceAsStream("/" + uri); if (in == null) { in = getClass().getResourceAsStream(uri); if (in == null) { logger.error("Failed to load configuration for resource '" + uri + "' from classpath."); } } return in; } private final String uri; private final Charset charset; private final ConfigManagerConfig internalConfig; public ConfigAdapterJson(@Nonnull final String uri, @Nonnull final Charset charset, @Nonnull final ConfigManagerConfig internalConfig) { this.uri = uri; this.charset = charset; this.internalConfig = internalConfig; } /** * Constant defined in configs of json format */ public static enum CONST { DEFAULTS { @Override public String toString() { return "_Defs_"; } }, SETS { @Override public String toString() { return "_Sets_"; } }, SETS_TYPE { @Override public String toString() { return "_Sets_Type_"; } }, KEY_LIST { @Override public String toString() { return "keyList"; } }, KEY { @Override public String toString() { return "key"; } }, /** * Used in place of default module when adapter is load via properties * file. * */ _PROP_ { @Override public String toString() { return "_prop_"; } } } /* * (non-Javadoc) * * @see * common.config.internal.ConfigAdapter#loadValue(common.config.internal * .ConfigAdapterJmx, java.lang.String) */ @Override public void loadValue(final ConfigManagerCache jmxloader) throws ConfigException { JsonObject confJson = null; InputStream in = getStream(uri, charset, internalConfig); if (null == in) { throw new ConfigException("Failed to load from json file: " + uri); } Reader reader = new BufferedReader(new InputStreamReader(in, charset)); JsonParser parser = new JsonParser(); try { confJson = (JsonObject) parser.parse(reader); } catch (JsonIOException e) { throw new ConfigException("Invalid json format for file " + uri); } catch (JsonSyntaxException e) { throw new ConfigException("Invalid json format for file " + uri); } try { reader.close(); in.close(); } catch (IOException e) { throw new ConfigException("Error while closing json config file ", e); } if (confJson != null && confJson.get("Modules") != null && confJson.get("Modules").isJsonObject()) { JsonObject modules = confJson.get("Modules").getAsJsonObject(); for (Entry<String, JsonElement> entry : modules.entrySet()) { if (entry.getValue() != null && entry.getValue().isJsonObject()) { jmxloader.insertValue(entry.getKey(), entry.getValue() .toString()); } else { throw new ConfigRuntimeException("Invalid config format: " + confJson); } } } else { throw new ConfigException( "Config format incorrect or file not found "); } } }