com.baasbox.configuration.PropertiesConfigurationHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.baasbox.configuration.PropertiesConfigurationHelper.java

Source

/*
 * 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