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

org.ff4j.web.controller.FeaturesController Maven / Gradle / Ivy

package org.ff4j.web.controller;

/*
 * #%L
 * ff4j-sample-web
 * %%
 * Copyright (C) 2013 - 2016 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 static org.ff4j.web.bean.WebConstants.DESCRIPTION;
import static org.ff4j.web.bean.WebConstants.GROUPNAME;
import static org.ff4j.web.bean.WebConstants.NEW_NAME;
import static org.ff4j.web.bean.WebConstants.OP_ADD_PERMISSION;
import static org.ff4j.web.bean.WebConstants.OP_CLEAR_PERMISSIONS;
import static org.ff4j.web.bean.WebConstants.OP_COPY_FEATURE;
import static org.ff4j.web.bean.WebConstants.OP_CREATE_FEATURE;
import static org.ff4j.web.bean.WebConstants.OP_DISABLE;
import static org.ff4j.web.bean.WebConstants.OP_EDIT_FEATURE;
import static org.ff4j.web.bean.WebConstants.OP_ENABLE;
import static org.ff4j.web.bean.WebConstants.OP_RENAME_FEATURE;
import static org.ff4j.web.bean.WebConstants.OP_RMV_FEATURE;
import static org.ff4j.web.bean.WebConstants.OP_RMV_PERMISSION;
import static org.ff4j.web.bean.WebConstants.OP_RMV_PROPERTY;
import static org.ff4j.web.bean.WebConstants.OP_TOGGLE_GROUP;
import static org.ff4j.web.bean.WebConstants.STRATEGY;
import static org.ff4j.web.bean.WebConstants.STRATEGY_INIT;
import static org.ff4j.web.bean.WebConstants.SUBOPERATION;
import static org.ff4j.web.embedded.ConsoleRenderer.msg;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ff4j.FF4j;
import org.ff4j.core.Feature;
import org.ff4j.core.FlippingStrategy;
import org.ff4j.utils.MappingUtil;
import org.ff4j.utils.Util;
import org.ff4j.web.bean.WebConstants;
import org.ff4j.web.embedded.ConsoleOperations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;

/**
 * Controller for main class
 *
 * @author Cedrick LUNVEN (@clunven)
 */
public class FeaturesController extends AbstractController {

	/** Logger for this class. */
    public static final Logger LOGGER = LoggerFactory.getLogger(FeaturesController.class);

    /** View name. */
	private static final String VIEW_FEATURES = "features";

	/** {@inheritDoc} */
	public FeaturesController(FF4j ff4j, TemplateEngine te) {
		super(ff4j, VIEW_FEATURES, te);
	}
	
    /** {@inheritDoc} */
    public void get(HttpServletRequest req, HttpServletResponse res, WebContext ctx) throws IOException {
        String operation = req.getParameter(WebConstants.OPERATION);
        String featureId = req.getParameter(WebConstants.FEATID);

        String msgType = "success";
        String msg = null;
        if (Util.hasLength(operation) && Util.hasLength(featureId)) {
            if (getFf4j().getFeatureStore().exist(featureId)) {
                
                if (OP_DISABLE.equalsIgnoreCase(operation)) {
                    getFf4j().disable(featureId);
                    msg = msg(featureId, "DISABLED");
                    LOGGER.info(featureId + " has been disabled");
                }
                
                if (OP_ENABLE.equalsIgnoreCase(operation)) {
                    getFf4j().enable(featureId);
                    msg = msg(featureId, "ENABLED");
                    LOGGER.info(featureId + " has been enabled");
                }
                
                if (OP_ADD_PERMISSION.equalsIgnoreCase(operation)) {
                    String permName = req.getParameter(WebConstants.PERMISSION);
                    Feature feature = getFf4j().getFeatureStore().read(featureId);
                    feature.getPermissions().add(permName);
                    getFf4j().getFeatureStore().update(feature);
                    LOGGER.info("Add new " + permName + " to " + featureId );
                }
                
                if (OP_RMV_PERMISSION.equalsIgnoreCase(operation)) {
                    String permName = req.getParameter(WebConstants.PERMISSION);
                    Feature feature = getFf4j().getFeatureStore().read(featureId);
                    feature.getPermissions().remove(permName);
                    getFf4j().getFeatureStore().update(feature);
                    LOGGER.info("Remove " + permName + " to " + featureId );
                }
                
                if (OP_CLEAR_PERMISSIONS.equalsIgnoreCase(operation)) {
                    Feature feature = getFf4j().getFeatureStore().read(featureId);
                    feature.getPermissions().clear();
                    getFf4j().getFeatureStore().update(feature);
                    LOGGER.info("Clear permissions for " + featureId);
                }
                
                if (OP_RMV_PROPERTY.equalsIgnoreCase(operation)) {
                    String propertyName = req.getParameter(WebConstants.NAME);
                    Feature feature     = getFf4j().getFeatureStore().read(featureId);
                    feature.getCustomProperties().remove(propertyName);
                    getFf4j().getFeatureStore().update(feature);
                    LOGGER.info("Remove Property " + propertyName + " to " + featureId );
                }
                    
            } else {
                msgType = "warning";
                msg = "The feature '" + featureId + "' does not exist";
            }
        }
        ctx.setVariable("msgType", msgType);
        ctx.setVariable("msgInfo", msg);
        renderPage(ctx);
    }

	/** {@inheritDoc} */
    public void post(HttpServletRequest req, HttpServletResponse res, WebContext ctx)
    throws IOException {
        String msg       = null;
        String msgType   = "success";
        String operation = req.getParameter(WebConstants.OPERATION);
        String featureId = req.getParameter(WebConstants.FEATID);
        
        if (OP_EDIT_FEATURE.equalsIgnoreCase(operation)) {
            this.updateFeature(req, featureId);
            msg = featureId + " has been UPDATED";
            
        } else if (OP_CREATE_FEATURE.equalsIgnoreCase(operation)) {
            ConsoleOperations.createFeature(getFf4j(), req);
            msg = featureId + " has been CREATED";
            
        } else if (OP_RMV_FEATURE.equalsIgnoreCase(operation)) {
            getFf4j().getFeatureStore().delete(featureId);
            msg = featureId + " has been DELETED";
            
        } else if (OP_RENAME_FEATURE.equalsIgnoreCase(operation)) {
            String newName = req.getParameter(NEW_NAME);
            Set< String> featureNames = getFf4j().getFeatureStore().readAll().keySet();
            if (featureNames.contains(newName)) {
                msgType = "warning";
                msg = "Cannot rename " + featureId + " to " + newName + " : it already exists";
            } else {
                Feature newFeature = getFf4j().getFeatureStore().read(featureId);
                newFeature.setUid(newName);
                getFf4j().getFeatureStore().delete(featureId);
                getFf4j().getFeatureStore().create(newFeature);
                msg = "Feature " + featureId + " has been renamed to " + newName;
            }
            
        } else if (OP_COPY_FEATURE.equalsIgnoreCase(operation)) {
            String newName = req.getParameter(NEW_NAME);
            Set< String> featureNames = getFf4j().getFeatureStore().readAll().keySet();
            if (featureNames.contains(newName)) {
                msgType = "warning";
                msg = "Cannot copy " + featureId + " with name " + newName + " : it already exists";
            } else {
                Feature newFeature = new Feature(getFf4j().getFeatureStore().read(featureId));
                newFeature.setUid(newName);
                getFf4j().getFeatureStore().create(newFeature);
                msg = "Feature " + featureId + " has been copied to " + newName;
            }
            
        } else if (OP_TOGGLE_GROUP.equalsIgnoreCase(operation)) {
            String groupName = req.getParameter(GROUPNAME);
            if (groupName != null && !groupName.isEmpty()) {
                String operationGroup = req.getParameter(SUBOPERATION);
                if (OP_ENABLE.equalsIgnoreCase(operationGroup)) {
                    getFf4j().getFeatureStore().enableGroup(groupName);
                    msg = groupName + " has been ENABLED";
                    LOGGER.info("Group '" + groupName + "' has been ENABLED.");
                } else if (OP_DISABLE.equalsIgnoreCase(operationGroup)) {
                    getFf4j().getFeatureStore().disableGroup(groupName);
                    msg = groupName + " has been DISABLED";
                    LOGGER.info("Group '" + groupName + "' has been DISABLED.");
                }
            }
        }
        
        ctx.setVariable("msgType", msgType);
        ctx.setVariable("msgInfo", msg);
        renderPage(ctx);
    }
    
    /**
     * Allow to update feature.
     *
     * @param featureId
     */
    private void updateFeature(HttpServletRequest req, String featureId) {
        Feature old = ff4j.getFeatureStore().read(featureId);
        // Core
        Feature fp = new Feature(featureId, old.isEnable());
        fp.setPermissions(old.getPermissions());
        fp.setCustomProperties(old.getCustomProperties());
        fp.setFlippingStrategy(buildFlippingStrategy(req, fp.getUid()));
        
        // Description
        final String featureDesc = req.getParameter(DESCRIPTION);
        if (Util.hasLength(featureDesc)) {
            fp.setDescription(featureDesc);
        }
        // GroupName
        final String groupName = req.getParameter(GROUPNAME);
        if (Util.hasLength(groupName)) {
            fp.setGroup(groupName);
        }
        // Creation
        ff4j.getFeatureStore().update(fp);
    }
  
    /**
     * Create Flipping Strategy from parameters.
     *
     * @param req
     *            current http query
     * @param uid
     *      unique feature identifier
     * @return instance of strategy
     */
    private FlippingStrategy buildFlippingStrategy(HttpServletRequest req, String uid) {
        String strategy = req.getParameter(STRATEGY);
        String strategyParams = req.getParameter(STRATEGY_INIT);
        FlippingStrategy fstrategy = null;
        Map initParams = new HashMap();
        if (Util.hasLength(strategy)) {
            if (Util.hasLength(strategyParams)) {
                String[] params = strategyParams.split(";");
                for (String currentP : params) {
                    String[] cur = currentP.split("=");
                    if (cur.length < 2) {
                        throw new IllegalArgumentException("Invalid Syntax : param1=val1,val2;param2=val3,val4");
                    }
                    initParams.put(cur[0], cur[1]);
                }
            }
            fstrategy = MappingUtil.instanceFlippingStrategy(uid, strategy, initParams);
        }
        return fstrategy;
    }

    /**
     * Both get and post operation will render the page.
     *
     * @param ctx
     *            current web context
     */
    private void renderPage(WebContext ctx) {
        ctx.setVariable(KEY_TITLE, "Features");

        // Sort natural Order
        Map mapOfFeatures = ff4j.getFeatureStore().readAll();
        List featuresNames = Arrays.asList(mapOfFeatures.keySet().toArray(new String[0]));
        Collections.sort(featuresNames);
        List orderedFeatures = new ArrayList();
        for (String featuName : featuresNames) {
            orderedFeatures.add(mapOfFeatures.get(featuName));
        }
        ctx.setVariable("listOfFeatures", orderedFeatures);

        // Get Group List
        List myGroupList = new ArrayList(ff4j.getFeatureStore().readAllGroups());
        Collections.sort(myGroupList);
        ctx.setVariable("groupList", myGroupList);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy