controllers.Features.java Source code

Java tutorial

Introduction

Here is the source code for controllers.Features.java

Source

// Features.java --- Controller that handles requests for listing and operating on features.

// Copyright (C) 2013-2015  Tim Krones

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package controllers;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.List;
import models.nodes.Feature;
import models.nodes.Value;
import play.Routes;
import play.libs.F.Function0;
import play.libs.F.Function;
import play.libs.F.Promise;
import play.libs.F.Tuple;
import play.libs.Json;
import play.mvc.BodyParser;
import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.Security;
import views.html.features;

public class Features extends Controller {

    private enum TargetAction {
        ADD, REMOVE;
    }

    @Security.Authenticated(Secured.class)
    public static Promise<Result> features() {
        Promise<List<Feature>> globalFeatureList = Feature.nodes.all();
        Promise<List<Value>> globalValueList = Value.nodes.all();
        Promise<Tuple<List<Feature>, List<Value>>> lists = globalFeatureList.zip(globalValueList);
        return lists.map(new Function<Tuple<List<Feature>, List<Value>>, Result>() {
            public Result apply(Tuple<List<Feature>, List<Value>> lists) {
                return ok(features.render(lists._1, lists._2));
            }
        });
    }

    @Security.Authenticated(Secured.class)
    @BodyParser.Of(BodyParser.Json.class)
    public static Promise<Result> create() {
        final JsonNode json = request().body().asJson();
        ObjectNode props = (ObjectNode) json.deepCopy();
        props.remove("targets");
        Promise<Boolean> created = Feature.nodes.create(props);
        return created.map(new Function<Boolean, Result>() {
            ObjectNode jsonResult = Json.newObject();

            public Result apply(Boolean created) {
                if (created) {
                    String name = json.get("name").asText();
                    jsonResult.put("id", name);
                    jsonResult.put("message", "Feature successfully created.");
                    return ok(jsonResult);
                }
                jsonResult.put("error", "Feature not created.");
                return badRequest(jsonResult);
            }
        });
    }

    @Security.Authenticated(Secured.class)
    @BodyParser.Of(BodyParser.Json.class)
    public static Promise<Result> updateName(final String name) {
        final ObjectNode newProps = (ObjectNode) request().body().asJson();
        newProps.retain("name", "description", "type");
        Promise<Boolean> nameTaken = Feature.nodes.exists(newProps);
        Promise<Boolean> updated = nameTaken.flatMap(new Function<Boolean, Promise<Boolean>>() {
            public Promise<Boolean> apply(Boolean nameTaken) {
                if (nameTaken) {
                    return Promise.pure(false);
                }
                ObjectNode oldProps = Json.newObject();
                oldProps.put("name", name);
                return Feature.nodes.update(oldProps, newProps);
            }
        });
        return updated.map(new Function<Boolean, Result>() {
            ObjectNode result = Json.newObject();

            public Result apply(Boolean updated) {
                if (updated) {
                    result.put("id", newProps.get("name").asText());
                    result.put("message", "Name successfully updated.");
                    return ok(result);
                }
                result.put("message", "Name not updated.");
                return badRequest(result);
            }
        });
    }

    @Security.Authenticated(Secured.class)
    @BodyParser.Of(BodyParser.Json.class)
    public static Promise<Result> updateDescription(String name) {
        ObjectNode newProps = (ObjectNode) request().body().asJson();
        newProps.retain("name", "description", "type");
        ObjectNode oldProps = newProps.deepCopy().retain("name");
        Promise<Boolean> updated = Feature.nodes.update(oldProps, newProps);
        return updated.map(new Function<Boolean, Result>() {
            ObjectNode result = Json.newObject();

            public Result apply(Boolean updated) {
                if (updated) {
                    result.put("message", "Description successfully updated.");
                    return ok(result);
                }
                result.put("message", "Description not updated.");
                return badRequest(result);
            }
        });
    }

    @Security.Authenticated(Secured.class)
    @BodyParser.Of(BodyParser.Json.class)
    public static Promise<Result> updateType(String name) {
        JsonNode json = request().body().asJson();
        final ObjectNode props = (ObjectNode) json.deepCopy();
        props.retain("name", "description", "type");
        // 1. Check if feature is orphaned
        Promise<Boolean> orphaned = Feature.nodes.orphaned(props);
        // 2. If it is, update its type
        Promise<Boolean> updated = orphaned.flatMap(new Function<Boolean, Promise<Boolean>>() {
            public Promise<Boolean> apply(Boolean orphaned) {
                if (orphaned) {
                    return Feature.nodes.setType(props);
                }
                return Promise.pure(false);
            }
        });
        return updated.map(new Function<Boolean, Result>() {
            ObjectNode jsonResult = Json.newObject();

            public Result apply(Boolean updated) {
                if (updated) {
                    jsonResult.put("message", "Type successfully updated.");
                    return ok(jsonResult);
                }
                jsonResult.put("message", "Type not updated.");
                return badRequest(jsonResult);
            }
        });
    }

    @Security.Authenticated(Secured.class)
    @BodyParser.Of(BodyParser.Json.class)
    public static Promise<Result> updateTargets(String name) {
        JsonNode json = request().body().asJson();
        TargetAction action = TargetAction.valueOf(json.findValue("action").asText());
        switch (action) {
        case ADD:
            return addTarget(name, json);
        case REMOVE:
            return removeTarget(name, json);
        default:
            return Promise.promise(new Function0<Result>() {
                ObjectNode result = Json.newObject();

                public Result apply() {
                    result.put("message", "Unknown action.");
                    return badRequest(result);
                }
            });
        }
    }

    @BodyParser.Of(BodyParser.Json.class)
    private static Promise<Result> addTarget(String name, JsonNode json) {
        ObjectNode feature = Json.newObject();
        feature.put("name", name);
        feature.put("type", json.get("type").asText());
        ObjectNode target = Json.newObject();
        target.put("name", json.get("target").asText());
        Promise<Boolean> connected = Feature.nodes.connect(feature, target);
        return connected.map(new Function<Boolean, Result>() {
            ObjectNode result = Json.newObject();

            public Result apply(Boolean connected) {
                if (connected) {
                    result.put("message", "Target successfully added.");
                    return ok(result);
                }
                result.put("message", "Target not added.");
                return badRequest(result);
            }
        });
    }

    @BodyParser.Of(BodyParser.Json.class)
    private static Promise<Result> removeTarget(String name, JsonNode json) {
        final ObjectNode feature = Json.newObject();
        feature.put("name", name);
        feature.put("type", json.get("type").asText());
        final ObjectNode target = Json.newObject();
        target.put("name", json.get("target").asText());
        // 1. Check if feature :HAS this target in some rule
        Promise<Boolean> hasValue = Feature.nodes.has(feature, target);
        // 2. If it doesn't, disconnect it from the target
        Promise<Boolean> disconnected = hasValue.flatMap(new Function<Boolean, Promise<Boolean>>() {
            public Promise<Boolean> apply(Boolean hasValue) {
                if (hasValue) {
                    return Promise.pure(false);
                }
                return Feature.nodes.disconnect(feature, target);
            }
        });
        return disconnected.map(new Function<Boolean, Result>() {
            ObjectNode result = Json.newObject();

            public Result apply(Boolean disconnected) {
                if (disconnected) {
                    result.put("message", "Target successfully removed.");
                    return ok(result);
                }
                result.put("message", "Target not removed.");
                return badRequest(result);
            }
        });
    }

    @Security.Authenticated(Secured.class)
    @BodyParser.Of(BodyParser.Json.class)
    public static Promise<Result> delete(final String name) {
        final ObjectNode props = Json.newObject();
        props.put("name", name);
        // 1. Check if feature is orphaned
        Promise<Boolean> orphaned = Feature.nodes.orphaned(props);
        Promise<Boolean> deleted = orphaned.flatMap(new Function<Boolean, Promise<Boolean>>() {
            public Promise<Boolean> apply(Boolean orphaned) {
                // 2. If it is, delete it
                if (orphaned) {
                    return Feature.nodes.delete(props);
                }
                return Promise.pure(false);
            }
        });
        return deleted.map(new Function<Boolean, Result>() {
            ObjectNode result = Json.newObject();

            public Result apply(Boolean deleted) {
                if (deleted) {
                    result.put("message", "Feature successfully deleted.");
                    return ok(result);
                }
                result.put("message", "Feature not deleted.");
                return badRequest(result);
            }
        });
    }

}