All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ff4j.utils.json.FeatureJsonParser Maven / Gradle / Ivy

package org.ff4j.utils.json;

/*
 * #%L
 * ff4j-web
 * %%
 * Copyright (C) 2013 - 2014 Ff4J
 * %%
 * 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.
 * #L%
 */

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.ff4j.core.Feature;
import org.ff4j.core.FlippingStrategy;
import org.ff4j.property.Property;
import org.ff4j.property.util.PropertyFactory;
import org.ff4j.utils.MappingUtil;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Unmarshalling data from JSON with Jackson.
 *
 * @author Cedrick LUNVEN
 */
public class FeatureJsonParser {

    /** Jackson mapper. */
    private static ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * Hide constructor.
     */
    private FeatureJsonParser() {
    }
    
    /**
     * Unmarshall {@link Feature} from json string.
     *
     * @param json
     *            json representation of feature.
     * @return feature object
     */
    @SuppressWarnings("unchecked")
    public static Feature parseFeature(String json) {
        try {
            return parseFeatureMap(objectMapper.readValue(json, HashMap.class));
        } catch (IOException e) {
            throw new IllegalArgumentException("Cannot parse json as Feature " + json, e);
        }
    }

    @SuppressWarnings("unchecked")
    private static Feature parseFeatureMap(Map fMap) {
        Feature f = new Feature((String) fMap.get("uid"));
        f.setEnable((Boolean) fMap.get("enable"));
        f.setDescription((String) fMap.get("description"));
        f.setGroup((String) fMap.get("group"));
        // permissions
        List perm = (ArrayList) fMap.get("permissions");
        f.setPermissions(new HashSet());
        if (perm != null) {
            f.getPermissions().addAll(perm);
        }
        // flipping strategy
        f.setFlippingStrategy(parseFlipStrategy(f.getUid(), (LinkedHashMap) fMap.get("flippingStrategy")));
        // custom properties
        Map  propertyMap = (Map < String, Object >) fMap.get("customProperties");
        f.setCustomProperties(parseCustomProperties(propertyMap));
        return f;
    }    
    
    /**
     * Parse the "customproperties" JSOn attribute.
     *
     * @param uid
     *      current feature identifier
     * @param tag
     *      current TAG
     * @return
     *      target map of properties
     */
    @SuppressWarnings("unchecked")
    private static Map < String, Property> parseCustomProperties(Map  customPTag) {
        Map < String, Property> myProperties = new LinkedHashMap>();
        if (null != customPTag && !customPTag.isEmpty()) {
            // Loop over properties
            for (Object property : customPTag.values()) {
                HashMap propertyJson = (HashMap) property;
                String propertyName = (String) propertyJson.get("name");
                String propertyVal  = String.valueOf(propertyJson.get("value"));
                String propertyType = (String) propertyJson.get("type");
                Property ap = PropertyFactory.createProperty(propertyName, propertyType, propertyVal);
                // FixedValued
                List  listOfFixedValue = (List) propertyJson.get("fixedValues");
                addFixedValuesToProperty(ap, listOfFixedValue);
                myProperties.put(ap.getName(), ap);
            }
        }
        return myProperties;
        
    }

    private static void addFixedValuesToProperty(Property ap, List listOfFixedValue) {
        if (listOfFixedValue != null) {
            for (Object v : listOfFixedValue) {
                ap.add2FixedValueFromString(String.valueOf(v));
            }
            // Check fixed value
            if (ap.getFixedValues() != null && !ap.getFixedValues().contains(ap.getValue())) {
                throw new IllegalArgumentException("Cannot create property <" + ap.getName() + 
                        "> invalid value <" + ap.getValue() + 
                        "> expected one of " + ap.getFixedValues());
            }
        }
    }

    /**
     * Convert feature array to json.
     *
     * @param features
     *            target features
     * @return json string
     */
    public static String featureArrayToJson(Feature[] features) {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        if (features != null) {
            boolean first = true;
            for (Feature feature : features) {
                sb.append(first ? "" : ",");
                sb.append(feature.toJson());
                first = false;
            }
        }
        sb.append("]");
        return sb.toString();
    }

    /**
     * Parse json string to get {@link FlippingStrategy}.
     * 
     * @param uid
     *            identifier
     * @param json
     *            json expression
     * @return flip strategy
     */
    @SuppressWarnings("unchecked")
    public static FlippingStrategy parseFlipStrategyAsJson(String uid, String json) {
        if (null == json || "".equals(json)) {
            return null;
        }
        try {
            return parseFlipStrategy(uid, (HashMap) objectMapper.readValue(json, HashMap.class));
        } catch (Exception e) {
            throw new IllegalArgumentException("Cannot parse JSON " + json, e);
        }
    }
    
    /**
     * Parse json string to get {@link FlippingStrategy}.
     * 
     * @param uid
     *            identifier
     * @param json
     *            json expression
     * @return flip strategy
     */
    @SuppressWarnings("unchecked")
    public static FlippingStrategy parseFlipStrategy(String uid, Map flipMap) {
        if (null == flipMap || flipMap.isEmpty()) {
            return null;
        }
        String classType = (String) flipMap.get("type");
        HashMap initparams = (HashMap) flipMap.get("initParams");
        return MappingUtil.instanceFlippingStrategy(uid, classType, initparams);
    }
    
    /**
     * Parse the json expression as array of {@link Feature}.
     *
     * @param json
     *      json expression
     * @return
     *      array of feature
     */
    @SuppressWarnings("unchecked")
    public static Feature[] parseFeatureArray(String json) {
        if (null == json || "".equals(json)) {
            return null;
        }
        try {
            List> flipMap = objectMapper.readValue(json, List.class);
            Feature[] fArray = new Feature[flipMap.size()];
            int idx = 0;
            for (LinkedHashMap ll : flipMap) {
                fArray[idx++] = parseFeatureMap(ll);
            }
            return fArray;
        } catch (Exception e) {
            throw new IllegalArgumentException("Cannot parse JSON " + json, e);
        }
    }

}