Package controllers

Source Code of controllers.IssueLabelApp

/**
* Yobi, Project Hosting SW
*
* Copyright 2012 NAVER Corp.
* http://yobi.io
*
* @Author Yi EungJun
*
* 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 controllers;

import controllers.annotation.IsAllowed;
import controllers.annotation.IsCreatable;
import models.IssueLabel;
import models.IssueLabelCategory;
import models.Project;
import models.enumeration.Operation;
import models.enumeration.ResourceType;
import play.data.DynamicForm;
import play.data.Form;
import play.db.ebean.Transactional;
import play.mvc.Controller;
import play.mvc.Http;
import play.mvc.Result;
import utils.ErrorViews;
import utils.HttpUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static play.data.Form.form;
import static play.libs.Json.toJson;

public class IssueLabelApp extends Controller {
    /**
     * Responds to a request for issue labels of the specified project.
     *
     * This method is used when put a label on an issue and list labels in
     * issue list page.
     *
     * Returns 403 Forbidden if the user has no permission to access to the
     * project.
     *
     * @param ownerName    the name of a project owner
     * @param projectName  the name of a project
     * @return the response to the request for issue labels
     */
    @IsAllowed(Operation.READ)
    public static Result labels(String ownerName, String projectName) {
        if (HttpUtil.isPJAXRequest(request())){
            return labelsAsPjax(ownerName, projectName);
        }

        return labelsAsJSON(ownerName, projectName);
    }

    /**
     * Retrieves a project corresponding to {@code ownerName} and {@code
     * projectName}, and returns its list of all issue labels in {@code
     * application/json}. Each label has four fields: {@link IssueLabel#id},
     * {@link IssueLabel#category}, {@link IssueLabel#color}, and {@link
     * IssueLabel#name}.
     *
     * Returns 406 Not Acceptable if the client cannot accept
     * {@code application/json}. Success response can only be returned when the
     * content type of the body is {@code application/json}.
     *
     * @param ownerName
     * @param projectName
     * @return the response to the request for issue labels
     */
    private static Result labelsAsJSON(String ownerName, String projectName) {
        if (!request().accepts("application/json")) {
            return status(Http.Status.NOT_ACCEPTABLE);
        }

        Project project = Project.findByOwnerAndProjectName(ownerName, projectName);

        List<Map<String, String>> labels = new ArrayList<>();
        for (IssueLabel label : IssueLabel.findByProject(project)) {
            Map<String, String> labelPropertyMap = new HashMap<>();
            labelPropertyMap.put("id", "" + label.id);
            labelPropertyMap.put("category", label.category.name);
            labelPropertyMap.put("categoryId", "" + label.category.id);
            labelPropertyMap.put("color", label.color);
            labelPropertyMap.put("name", label.name);
            labels.add(labelPropertyMap);
        }

        response().setHeader("Content-Type", "application/json");
        return ok(toJson(labels));
    }

    private static Result labelsAsPjax(String ownerName, String projectName){
        response().setHeader("Cache-Control", "no-cache, no-store");

        Project project = Project.findByOwnerAndProjectName(ownerName, projectName);
        List<IssueLabel> labels = IssueLabel.findByProject(project);

        return ok(views.html.project.partial_issuelabels_list.render(project, labels));
    }

    @IsAllowed(Operation.UPDATE)
    public static Result labelsForm(String ownerName, String projectName){
        Project project = Project.findByOwnerAndProjectName(ownerName, projectName);
        List<IssueLabel> labels = IssueLabel.findByProject(project);

        return ok(views.html.project.issuelabels.render(project, labels));
    }

    /**
     * Responds to a request to add an issue label for the specified project.
     *
     * This method is used when a user tries to add a issue label in issue list,
     * editing issue or new issue page.
     *
     * Adds an issue label created with values taken from
     * {@link Form#bindFromRequest(java.util.Map, String...)} in the project
     * specified by the {@code ownerName} and {@code projectName}. But if there
     * has already been the same issue label in category, name and color, then
     * this method returns an empty 204 No Content response.
     *
     * When a new label is added, this method encodes the label's fields:
     * {@link IssueLabel#id}, {@link IssueLabel#name}, {@link IssueLabel#color},
     * and {@link IssueLabel#category} into {@code application/json}, and
     * includes them in the body of the 201 Created response. But if the client
     * cannot accept {@code application/json}, it returns the 201 Created with
     * no response body.
     *
     * Returns 403 Forbidden, if the user has no permission to add a new label
     * in the project.
     *
     * @param ownerName    the name of a project owner
     * @param projectName  the name of a project
     * @return             the response to the request to add a new issue label
     */
    @Transactional
    @IsCreatable(ResourceType.ISSUE_LABEL)
    public static Result newLabel(String ownerName, String projectName) {
        Project project = Project.findByOwnerAndProjectName(ownerName, projectName);

        DynamicForm labelForm = form().bindFromRequest();
        String categoryName = labelForm.get("categoryName");

        IssueLabelCategory category = new IssueLabelCategory();
        category.project = project;
        category.name = categoryName;

        if (category.exists()) {
            category = IssueLabelCategory.findBy(category);
        } else {
            category.isExclusive = Boolean.parseBoolean(labelForm.get("categoryIsExclusive"));
            category.save();
        }

        IssueLabel label = new IssueLabel();
        label.project = project;
        label.name = labelForm.get("labelName");
        label.color = labelForm.get("labelColor");
        label.category = category;

        if (label.exists()) {
            return noContent();
        } else {
            label.save();

            if (!request().accepts("application/json")) {
                return created();
            }

            response().setHeader("Content-Type", "application/json");

            Map<String, String> labelPropertyMap = new HashMap<>();
            labelPropertyMap.put("id", "" + label.id);
            labelPropertyMap.put("name", label.name);
            labelPropertyMap.put("color", label.color);
            labelPropertyMap.put("category", label.category.name);
            labelPropertyMap.put("categoryId", "" + label.category.id);

            return created(toJson(labelPropertyMap));
        }
    }

    /**
     * Responds to a request to delete the specified issue label.
     *
     * This method is used when a user click a button to delete a issue label
     * in issue list, editing issue or new issue page.
     *
     * Deletes an issue label corresponding to the given {@code id}.
     *
     * - Returns {@code 200 OK} if the issue label is deleted succesfully.
     * - Returns {@code 403 Forbidden} if the user has no permission to delete
     *   the issue label.
     * - Returns {@code 404 Not Found} if no issue label is found.
     *
     * The request must have a {@code _method} parameter and the parameter
     * value must be case-insensitive "delete"; otherwise, returns 400 Bad
     * Request. We use this trick because an HTML Form does not support the
     * DELETE method.
     *
     * @param ownerName    Don't use.
     * @param projectName  Don't use.
     * @param id           the id of the label to be deleted
     * @return             the response to the request to delete an issue label
     */
    @Transactional
    @IsAllowed(value = Operation.DELETE, resourceType = ResourceType.ISSUE_LABEL)
    public static Result delete(String ownerName, String projectName, Long id) {
        // _method must be 'delete'
        DynamicForm bindedForm = form().bindFromRequest();
        if (!bindedForm.get("_method").toLowerCase()
                .equals("delete")) {
            return badRequest(ErrorViews.BadRequest.render("_method must be 'delete'."));
        }

        IssueLabel label = IssueLabel.finder.byId(id);
        label.delete();
        return ok();
    }

    @IsAllowed(value = Operation.UPDATE, resourceType = ResourceType.ISSUE_LABEL)
    public static Result update(String ownerName, String projectName, Long id) {
        Form<IssueLabel> form = new Form<>(IssueLabel.class).bindFromRequest();

        if (form.hasErrors()) {
            return badRequest();
        }

        IssueLabel label = form.get();
        label.id = id;
        label.project = Project.findByOwnerAndProjectName(ownerName, projectName);

        label.update();

        return ok();
    }

    /**
     * Responds to a request for the CSS styles of all issue labels in the
     * specified project.
     *
     * This method is used when CSS styles of issue labels are required in any
     * page which uses issue label.
     *
     * @param ownerName    the name of a project owner
     * @param projectName  the name of a project
     * @return the response to the request for the css styles in text/css.
     */
    @IsAllowed(Operation.READ)
    public static Result labelStyles(String ownerName, String projectName) {
        Project project = Project.findByOwnerAndProjectName(ownerName, projectName);
        List<IssueLabel> labels = IssueLabel.findByProject(project);

        String eTag = "\"" + labels.hashCode() + "\"";
        String ifNoneMatchValue = request().getHeader("If-None-Match");

        if(ifNoneMatchValue != null && ifNoneMatchValue.equals(eTag)) {
            response().setHeader("ETag", eTag);
            return status(NOT_MODIFIED);
        }

        response().setHeader("ETag", eTag);

        return ok(views.html.common.issueLabelColor.render(labels)).as("text/css");
    }

    /**
     * Responds to a request for issue label categories of the specified
     * project.
     *
     * Retrieves a project corresponding to {@code ownerName} and
     * {@code projectName}, and returns its list of all issue label categories
     * in {@code application/json}. Each category has three fields:
     * {@link IssueLabelCategory#id}, {@link IssueLabelCategory#name},
     * {@link IssueLabelCategory#isExclusive}.
     *
     * Returns 403 Forbidden if the user has no permission to access to the
     * project.
     *
     * Returns 406 Not Acceptable if the client cannot accept
     * {@code application/json}. Success response can only be returned when the
     * content type of the body is {@code application/json}.
     *
     * @param ownerName    the name of a project owner
     * @param projectName  the name of a project
     * @return the response to the request for issue label categories
     */
    @IsAllowed(Operation.READ)
    public static Result categories(String ownerName, String projectName) {
        if (!request().accepts("application/json")) {
            return status(Http.Status.NOT_ACCEPTABLE);
        }

        Project project =
            Project.findByOwnerAndProjectName(ownerName, projectName);

        List<Map<String, String>> categories = new ArrayList<>();
        for (IssueLabelCategory category
                : IssueLabelCategory.findByProject(project)) {
            categories.add(toMap(category));
        }

        return ok(toJson(categories)).as("application/json");
    }

    /**
     * Responds to a request for an issue label category.
     *
     * Returns 406 Not Acceptable if the client cannot accept
     * {@code application/json}. Success response can only be returned when the
     * content type of the body is {@code application/json}.
     *
     * @param ownerName    Don't use.
     * @param projectName  Don't use.
     * @param id           the id of the category
     * @return the response to the request for an issue label category
     */
    @IsAllowed(value = Operation.READ,
            resourceType = ResourceType.ISSUE_LABEL_CATEGORY)
    public static Result category(String ownerName, String projectName,
            Long id) {
        if (!request().accepts("application/json")) {
            return status(Http.Status.NOT_ACCEPTABLE);
        }

        Project project =
            Project.findByOwnerAndProjectName(ownerName, projectName);

        IssueLabelCategory category = IssueLabelCategory.find.byId(id);

        return ok(toJson(toMap(category))).as("application/json");
    }

    @IsAllowed(value = Operation.UPDATE,
            resourceType = ResourceType.ISSUE_LABEL_CATEGORY)
    public static Result updateCategory(String ownerName, String projectName,
            Long id) {
        Form<IssueLabelCategory> form =
            new Form<>(IssueLabelCategory.class).bindFromRequest();

        if (form.hasErrors()) {
            return badRequest();
        }

        IssueLabelCategory category = form.get();
        category.id = id;
        category.project =
            Project.findByOwnerAndProjectName(ownerName, projectName);

        category.update();

        return ok();
    }

    /**
     * Responds to a request to add an issue label category for the specified
     * project.
     *
     * Adds an issue label category created with values taken from
     * {@link Form#bindFromRequest(java.util.Map, String...)} in the project
     * specified by the {@code ownerName} and {@code projectName}. But if there
     * has already been the same issue label category in name, then this method
     * returns an empty 204 No Content response.
     *
     * When a new category is added, this method encodes the category's fields:
     * {@link IssueLabelCategory#id}, {@link IssueLabelCategory#name},
     * {@link IssueLabelCategory#isExclusive}, and includes them in the body of
     * the 201 Created response. But if the client cannot accept
     * {@code application/json}, it returns the 201 Created with no response
     * body.
     *
     * @param ownerName    the name of a project owner
     * @param projectName  the name of a project
     * @return             the response to the request to add a new issue label
     *                     category
     */
    @IsCreatable(ResourceType.ISSUE_LABEL_CATEGORY)
    public static Result newCategory(String ownerName, String projectName) {
        Form<IssueLabelCategory> form =
            new Form<>(IssueLabelCategory.class).bindFromRequest();

        if (form.hasErrors()) {
            return badRequest();
        }

        IssueLabelCategory category = form.get();

        category.project =
            Project.findByOwnerAndProjectName(ownerName, projectName);

        if (category.exists()) {
            return noContent();
        }

        category.save();

        if (!request().accepts("application/json")) {
            return created();
        }

        Map<String, String> categoryPropertyMap = new HashMap<>();
        categoryPropertyMap.put("id", "" + category.id);
        categoryPropertyMap.put("name", category.name);
        categoryPropertyMap.put("isExclusive", "" + category.isExclusive);

        return created(toJson(categoryPropertyMap)).as("application/json");
    }

    @Transactional
    @IsAllowed(value = Operation.DELETE, resourceType = ResourceType.ISSUE_LABEL_CATEGORY)
    public static Result deleteCategory(String ownerName, String projectName, Long id) {
        IssueLabelCategory.find.byId(id).delete();
        return ok();
    }

    private static Map<String, String> toMap(IssueLabelCategory category) {
        Map<String, String> map = new HashMap<>();
        map.put("id", "" + category.id);
        map.put("name", category.name);
        map.put("isExclusive", "" + category.isExclusive);
        return map;
    }
}
TOP

Related Classes of controllers.IssueLabelApp

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.