Java tutorial
/* * Copyright (c) 2014. * * BaasBox - info-at-baasbox.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.baasbox.configuration; import java.io.StringWriter; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.EnumSet; import org.apache.commons.lang3.StringUtils; import com.baasbox.service.logging.BaasBoxLogger; import com.baasbox.exception.ConfigurationException; import com.baasbox.service.push.PushNotInitializedException; import com.baasbox.service.push.PushSwitchException; import com.baasbox.service.push.providers.PushInvalidApiKeyException; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableMap; public class PropertiesConfigurationHelper { /*** * This are the [sections] inside the configuration.conf file. * Each of them maps an Enum */ public static final ImmutableMap<String, Class> CONFIGURATION_SECTIONS = ImmutableMap.of("PasswordRecovery", (Class) PasswordRecovery.class, "Application", (Class) Application.class, "Push", (Class) Push.class, "Images", (Class) ImagesConfiguration.class, "Social", (Class) SocialLoginConfiguration.class); /*** * * Returns a json representation of the Enumerator * The Enumerator must implements the IProperties interface * @param en the Enumerator to serialize. It must implements the IProperties interface * @return the representation of the Enumerator */ @SuppressWarnings("unchecked") public static String dumpConfigurationAsJson(String section) { Class en = CONFIGURATION_SECTIONS.get(section); try { JsonFactory jfactory = new JsonFactory(); StringWriter sw = new StringWriter(); String enumDescription = ""; JsonGenerator gen = jfactory.createJsonGenerator(sw); Method getEnumDescription = en.getMethod("getEnumDescription"); if (getEnumDescription != null && getEnumDescription.getReturnType() == String.class && Modifier.isStatic(getEnumDescription.getModifiers())) enumDescription = (String) getEnumDescription.invoke(null); gen.writeStartObject(); //{ gen.writeStringField("section", section); // "configuration":"EnumName" gen.writeStringField("description", enumDescription); // ,"description": "EnumDescription" gen.writeFieldName("sub sections"); // ,"sections": gen.writeStartObject(); // { String lastSection = ""; EnumSet values = EnumSet.allOf(en); for (Object v : values) { String key = (String) (en.getMethod("getKey")).invoke(v); boolean isVisible = (Boolean) (en.getMethod("isVisible")).invoke(v); String valueAsString; if (isVisible) valueAsString = (String) (en.getMethod("getValueAsString")).invoke(v); else valueAsString = "--HIDDEN--"; boolean isEditable = (Boolean) (en.getMethod("isEditable")).invoke(v); String valueDescription = (String) (en.getMethod("getValueDescription")).invoke(v); Class type = (Class) en.getMethod("getType").invoke(v); String subsection = key.substring(0, key.indexOf('.')); if (!lastSection.equals(subsection)) { if (gen.getOutputContext().inArray()) gen.writeEndArray(); gen.writeFieldName(subsection); // "sectionName": gen.writeStartArray(); // [ lastSection = subsection; } boolean isOverridden = (Boolean) (en.getMethod("isOverridden")).invoke(v); gen.writeStartObject(); // { gen.writeStringField(key, valueAsString); // "key": "value" gen.writeStringField("description", valueDescription); // ,"description":"description" gen.writeStringField("type", type.getSimpleName()); // ,"type":"type" gen.writeBooleanField("editable", isEditable); // ,"editable":"true|false" gen.writeBooleanField("visible", isVisible); // ,"visible":"true|false" gen.writeBooleanField("overridden", isOverridden); // ,"overridden":"true|false" gen.writeEndObject(); // } } if (gen.getOutputContext().inArray()) gen.writeEndArray(); // ] gen.writeEndObject(); // } gen.writeEndObject(); //} gen.close(); return sw.toString(); } catch (Exception e) { BaasBoxLogger.error("Cannot generate a json for " + en.getSimpleName() + " Enum. Is it an Enum that implements the IProperties interface?", e); } return "{}"; }//dumpConfigurationAsJson(en) public static String dumpConfigurationAsJson() { ImmutableCollection<String> keys = CONFIGURATION_SECTIONS.keySet(); ObjectMapper mapper = new ObjectMapper(); JsonFactory jfactory = mapper.getJsonFactory(); StringWriter sw = new StringWriter(); try { JsonGenerator gen = jfactory.createJsonGenerator(sw); gen.writeStartArray(); for (String v : keys) { String st = dumpConfigurationAsJson(v); ObjectMapper op = new ObjectMapper(); JsonNode p = op.readTree(st); BaasBoxLogger.debug("OBJECT:" + p.toString()); BaasBoxLogger.debug("STRING:" + st); //JsonParser jp = jfactory.createJsonParser(st); gen.writeTree(p); } gen.writeEndArray(); gen.close(); return sw.toString(); } catch (Exception e) { BaasBoxLogger.error("Cannot generate a json for the configuration", e); } return "[]"; }//dumpConfigurationAsJson() public static String dumpConfiguration() { ImmutableCollection<String> keys = CONFIGURATION_SECTIONS.keySet(); StringBuilder sb = new StringBuilder(); for (String v : keys) { sb.append(dumpConfiguration(v)); sb.append("\n"); } return sb.toString(); }//dumpConfiguration() public static String dumpConfiguration(String section) { Class en = CONFIGURATION_SECTIONS.get(section); try { StringBuilder sb = new StringBuilder(); String enumDescription = ""; Method getEnumDescription = en.getMethod("getEnumDescription"); if (getEnumDescription != null && getEnumDescription.getReturnType() == String.class && Modifier.isStatic(getEnumDescription.getModifiers())) enumDescription = (String) getEnumDescription.invoke(null); sb.append(enumDescription); sb.append("\n"); sb.append(section.toUpperCase()); sb.append("\n"); String lastSection = ""; EnumSet values = EnumSet.allOf(en); for (Object v : values) { String key = (String) ((Method) v.getClass().getMethod("getKey")).invoke(v); Object value = ((Method) en.getMethod("getValue")).invoke(v); String subsection = key.substring(0, key.indexOf('.')); if (!lastSection.equals(subsection)) { sb.append(" - "); sb.append(subsection.toUpperCase()); sb.append("\n"); lastSection = subsection; } sb.append(" + "); sb.append(key); sb.append(" = "); sb.append(value); sb.append("\n"); } return sb.toString(); } catch (Exception e) { BaasBoxLogger.error("Cannot generate a json for " + en.getSimpleName() + " Enum. Is it an Enum that implements the IProperties interface?", e); } return ""; }//dumpConfiguration public static String dumpConfigurationSectionAsFlatJson(String section) { Class en = CONFIGURATION_SECTIONS.get(section); try { JsonFactory jfactory = new JsonFactory(); StringWriter sw = new StringWriter(); String enumDescription = ""; JsonGenerator gen = jfactory.createJsonGenerator(sw); gen.writeStartArray(); EnumSet values = EnumSet.allOf(en); for (Object v : values) { String key = (String) (en.getMethod("getKey")).invoke(v); boolean isVisible = (Boolean) (en.getMethod("isVisible")).invoke(v); String valueAsString; if (isVisible) valueAsString = (String) (en.getMethod("getValueAsString")).invoke(v); else valueAsString = "--HIDDEN--"; boolean isEditable = (Boolean) (en.getMethod("isEditable")).invoke(v); boolean isOverridden = (Boolean) (en.getMethod("isOverridden")).invoke(v); String valueDescription = (String) (en.getMethod("getValueDescription")).invoke(v); Class type = (Class) en.getMethod("getType").invoke(v); gen.writeStartObject(); // { gen.writeStringField("key", key); gen.writeStringField("value", valueAsString); gen.writeStringField("description", valueDescription); // ,"description":"description" gen.writeStringField("type", type.getSimpleName()); // ,"type":"type" gen.writeBooleanField("editable", isEditable); gen.writeBooleanField("overridden", isOverridden); gen.writeEndObject(); // } } if (gen.getOutputContext().inArray()) gen.writeEndArray(); // ] gen.close(); return sw.toString(); } catch (Exception e) { BaasBoxLogger.error("Cannot generate a json for " + en.getSimpleName() + " Enum. Is it an Enum that implements the IProperties interface?", e); } return "{}"; }//dumpConfigurationSectionAsJson(String)() /*** * Returns an Enumerator value by its key * The Enumerator must implement the IProperties interface * @param en * @param iKey * @return the enumerator value * @throws ConfigurationException * @throws Exception if the en Class is not an Enumerator that implements the IProperties interface */ public static Object findByKey(Class en, String iKey) throws ConfigurationException { EnumSet values = EnumSet.allOf(en); for (Object v : values) { try { if (((String) en.getMethod("getKey").invoke(v)).equalsIgnoreCase(iKey)) return v; } catch (Exception e) { throw new ConfigurationException( "Is it " + en.getCanonicalName() + " an Enum that implements the IProperties interface?", e); } } return null; } //findByKey public static Object findByKey(String completeKey) throws ConfigurationException { String[] splittedKeys = completeKey.split("\\."); String section = splittedKeys[0]; Class en = PropertiesConfigurationHelper.CONFIGURATION_SECTIONS.get(section); EnumSet values = EnumSet.allOf(en); for (Object v : values) { try { String key = StringUtils.join(Arrays.copyOfRange(splittedKeys, 1, splittedKeys.length), "."); if (((String) en.getMethod("getKey").invoke(v)).equalsIgnoreCase(key)) return v; } catch (Exception e) { throw new ConfigurationException( "Is it " + en.getCanonicalName() + " an Enum that implements the IProperties interface?", e); } } return null; } //findByKey /*** * Set an Enumerator value. * The Enumerator class must implement the IProperties interface * @param en The Enumerator class * @param iKey * @param value * @throws ConfigurationException * @throws PushNotInitializedException * @throws PushSwitchException * @throws Exception */ public static void setByKey(Class en, String iKey, Object value) throws ConfigurationException { Object enumValue = findByKey(en, iKey); try { en.getMethod("setValue", Object.class).invoke(enumValue, value); } catch (Exception e) { if (e.getCause() instanceof IllegalStateException) throw new IllegalStateException(e.getCause()); if (e.getCause() instanceof PushSwitchException) throw (PushSwitchException) e.getCause(); if (e.getCause() instanceof PushNotInitializedException) throw (PushNotInitializedException) e.getCause(); if (e.getCause() instanceof PushInvalidApiKeyException) throw (PushInvalidApiKeyException) e.getCause(); throw new ConfigurationException("Invalid key (" + iKey + ") or value (" + value + ")", e); } } //setByKey public static void override(String completeKey, Object value) throws ConfigurationException { Object enumValue = findByKey(completeKey); try { String[] splittedKeys = completeKey.split("\\."); String section = splittedKeys[0]; Class en = PropertiesConfigurationHelper.CONFIGURATION_SECTIONS.get(section); en.getMethod("override", Object.class).invoke(enumValue, value); } catch (Exception e) { throw new ConfigurationException("Invalid key -" + completeKey + "- or value -" + value + "-", e); } } public static void setVisible(String completeKey, Boolean value) throws ConfigurationException { Object enumValue = findByKey(completeKey); try { String[] splittedKeys = completeKey.split("\\."); String section = splittedKeys[0]; Class en = PropertiesConfigurationHelper.CONFIGURATION_SECTIONS.get(section); en.getMethod("setVisible", boolean.class).invoke(enumValue, value); } catch (Exception e) { BaasBoxLogger.error("Invalid key -" + completeKey + "- or value -" + value + "-", e); throw new ConfigurationException("Invalid key -" + completeKey + "- or value -" + value + "-", e); } } public static void setEditable(String completeKey, Boolean value) throws ConfigurationException { Object enumValue = findByKey(completeKey); try { String[] splittedKeys = completeKey.split("\\."); String section = splittedKeys[0]; Class en = PropertiesConfigurationHelper.CONFIGURATION_SECTIONS.get(section); en.getMethod("setEditable", boolean.class).invoke(enumValue, value); } catch (Exception e) { BaasBoxLogger.error("Invalid key -" + completeKey + "- or value -" + value + "-", e); throw new ConfigurationException("Invalid key -" + completeKey + "- or value -" + value + "-", e); } } }//PropertiesConfigurationHelper