jp.aegif.nemaki.rest.GroupResource.java Source code

Java tutorial

Introduction

Here is the source code for jp.aegif.nemaki.rest.GroupResource.java

Source

/*******************************************************************************
 * Copyright (c) 2013 aegif.
 *
 * This file is part of NemakiWare.
 *
 * NemakiWare is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * NemakiWare 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with NemakiWare.
 * If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     linzhixing(https://github.com/linzhixing) - initial API and implementation
 ******************************************************************************/
package jp.aegif.nemaki.rest;

import jp.aegif.nemaki.common.ErrorCode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import jp.aegif.nemaki.businesslogic.PrincipalService;
import jp.aegif.nemaki.model.Group;
import jp.aegif.nemaki.model.User;

import org.apache.commons.lang.StringUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

@Path("/repo/{repositoryId}/group")
public class GroupResource extends ResourceBase {

    PrincipalService principalService;

    @SuppressWarnings("unchecked")
    @GET
    @Path("/search")
    @Produces(MediaType.APPLICATION_JSON)
    public String search(@PathParam("repositoryId") String repositoryId, @QueryParam("query") String query) {
        boolean status = true;
        JSONObject result = new JSONObject();
        JSONArray errMsg = new JSONArray();

        List<Group> groups = this.principalService.getGroups(repositoryId);
        JSONArray queriedGroups = new JSONArray();

        for (Group g : groups) {
            if (g.getGroupId().startsWith(query) || g.getName().startsWith(query)) {
                queriedGroups.add(this.convertGroupToJson(g));
            }
        }

        if (queriedGroups.size() == 0) {
            status = false;
            addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_NOTFOUND);
        } else {
            result.put("result", queriedGroups);
        }

        result = makeResult(status, result, errMsg);
        return result.toString();
    }

    @SuppressWarnings("unchecked")
    @GET
    @Path("/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String list(@PathParam("repositoryId") String repositoryId) {
        boolean status = true;
        JSONObject result = new JSONObject();
        JSONArray listJSON = new JSONArray();
        JSONArray errMsg = new JSONArray();

        List<Group> groupList;
        try {
            groupList = principalService.getGroups(repositoryId);
            for (Group group : groupList) {
                JSONObject groupJSON = convertGroupToJson(group);
                listJSON.add(groupJSON);
            }
            result.put(ITEM_ALLGROUPS, listJSON);
        } catch (Exception ex) {
            ex.printStackTrace();
            addErrMsg(errMsg, ITEM_ALLGROUPS, ErrorCode.ERR_LIST);
        }
        result = makeResult(status, result, errMsg);
        return result.toString();
    }

    @SuppressWarnings("unchecked")
    @GET
    @Path("/show/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public String show(@PathParam("repositoryId") String repositoryId, @PathParam("id") String groupId) {
        boolean status = true;
        JSONObject result = new JSONObject();
        JSONArray errMsg = new JSONArray();

        Group group = principalService.getGroupById(repositoryId, groupId);
        if (group == null) {
            status = false;
            addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_NOTFOUND);
        } else {
            result.put("group", convertGroupToJson(group));
        }
        makeResult(status, result, errMsg);
        return result.toString();
    }

    @SuppressWarnings("unchecked")
    @POST
    @Path("/create/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public String create(@PathParam("repositoryId") String repositoryId, @PathParam("id") String groupId,
            @FormParam(FORM_GROUPNAME) String name, @FormParam("users") String users,
            @FormParam("groups") String groups, @Context HttpServletRequest httpRequest) {

        boolean status = true;
        JSONObject result = new JSONObject();
        JSONArray errMsg = new JSONArray();

        //Validation
        status = validateNewGroup(repositoryId, status, errMsg, groupId, name);

        //Edit group info
        JSONArray _users = parseJsonArray(users);
        JSONArray _groups = parseJsonArray(groups);
        Group group = new Group(groupId, name, _users, _groups);
        setFirstSignature(httpRequest, group);

        //Create a group
        if (status) {
            try {
                principalService.createGroup(repositoryId, group);
            } catch (Exception ex) {
                ex.printStackTrace();
                status = false;
                addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_CREATE);
            }
        }
        result = makeResult(status, result, errMsg);
        return result.toString();
    }

    @PUT
    @Path("/update/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public String update(@PathParam("repositoryId") String repositoryId, @PathParam("id") String groupId,
            @FormParam(FORM_GROUPNAME) String name, @FormParam("users") String users,
            @FormParam("groups") String groups, @Context HttpServletRequest httpRequest) {

        boolean status = true;
        JSONObject result = new JSONObject();
        JSONArray errMsg = new JSONArray();

        //Existing group
        Group group = principalService.getGroupById(repositoryId, groupId);

        //Validation
        status = validateGroup(status, errMsg, groupId, name);

        //Edit & Update
        if (status) {
            //Edit group info
            //if a parameter is not input, it won't be modified.
            group.setName(name);
            group.setUsers(parseJsonArray(users));
            group.setGroups(parseJsonArray(groups));
            setModifiedSignature(httpRequest, group);

            try {
                principalService.updateGroup(repositoryId, group);
            } catch (Exception ex) {
                ex.printStackTrace();
                status = false;
                addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_UPDATE);
            }
        }
        result = makeResult(status, result, errMsg);
        return result.toString();
    }

    @DELETE
    @Path("/delete/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public String delete(@PathParam("repositoryId") String repositoryId, @PathParam("id") String groupId) {

        boolean status = true;
        JSONObject result = new JSONObject();
        JSONArray errMsg = new JSONArray();

        //Existing group
        Group group = principalService.getGroupById(repositoryId, groupId);
        if (group == null) {
            status = false;
            addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_NOTFOUND);
        }

        //Delete the group
        if (status) {
            try {
                principalService.deleteGroup(repositoryId, group.getId());
            } catch (Exception ex) {
                addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_DELETE);
            }
        }
        result = makeResult(status, result, errMsg);
        return result.toString();
    }

    @PUT
    @Path("/{apiType: add|remove}/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public String updateMembers(@PathParam("repositoryId") String repositoryId, @PathParam("id") String groupId,
            @PathParam("apiType") String apiType, @FormParam(FORM_MEMBER_USERS) String users,
            @FormParam(FORM_MEMBER_GROUPS) String groups, @Context HttpServletRequest httpRequest) {
        boolean status = true;
        JSONObject result = new JSONObject();
        JSONArray errMsg = new JSONArray();

        //Existing Group
        Group group = principalService.getGroupById(repositoryId, groupId);
        if (group == null) {
            status = false;
            addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_NOTFOUND);
        }

        //Parse JSON string from input parameter
        JSONArray usersAry = new JSONArray();
        if (users != null) {
            try {
                usersAry = (JSONArray) JSONValue.parseWithException(users); //JSON parse validation
            } catch (Exception ex) {
                ex.printStackTrace();
                status = false;
                addErrMsg(errMsg, ITEM_MEMBER_USERS, ErrorCode.ERR_PARSEJSON);
            }
        }

        JSONArray groupsAry = new JSONArray();
        if (groups != null) {
            try {
                groupsAry = (JSONArray) JSONValue.parseWithException(groups); //JSON parse validation
            } catch (Exception ex) {
                ex.printStackTrace();
                status = false;
                addErrMsg(errMsg, ITEM_MEMBER_GROUPS, ErrorCode.ERR_PARSEJSON);
            }
        }

        //Edit members info of the group
        if (status) {
            //Group info
            setModifiedSignature(httpRequest, group);

            //Member(User) info
            List<String> usersList = editUserMembers(repositoryId, usersAry, errMsg, apiType, group);
            group.setUsers(usersList);

            //Member(Group) info
            List<String> groupsList = editGroupMembers(repositoryId, groupsAry, errMsg, apiType, group);
            group.setGroups(groupsList);

            //Update
            if (apiType.equals(API_ADD)) {
                try {
                    principalService.updateGroup(repositoryId, group);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    status = false;
                    addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_UPDATEMEMBERS);
                }
            } else if (apiType.equals(API_REMOVE)) {
                try {
                    principalService.updateGroup(repositoryId, group);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    status = false;
                    addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_UPDATEMEMBERS);
                }
            }
        }

        result = makeResult(status, result, errMsg);
        return result.toJSONString();
    }

    /**
     *if list is null, return true.
     * @param errMsg
     * @param id
     * @param list
     * @return
     */
    private boolean isNewRecord(JSONArray errMsg, String id, List<String> list) {
        boolean status = true;
        if (list != null) {
            for (String s : list) {
                if (id.equals(s)) {
                    status = false;
                    break;
                }
            }
        }
        return status;
    }

    /**
     * edit group's members(users)
     * @param repositoryId TODO
     * @param usersAry
     * @param errMsg
     * @param apiType
     * @param group
     * @return
     */
    private List<String> editUserMembers(String repositoryId, JSONArray usersAry, JSONArray errMsg, String apiType,
            Group group) {
        List<String> usersList = new ArrayList<String>();

        List<String> ul = group.getUsers();
        if (ul != null)
            usersList = ul;

        for (final Object obj : usersAry) {
            boolean notSkip = true;
            JSONObject objJSON = (JSONObject) obj;
            String userId = (String) objJSON.get(FORM_ID);

            //check only when "add" API
            if (apiType.equals(API_ADD)) {
                User existingUser = principalService.getUserById(repositoryId, userId);
                if (existingUser == null) {
                    notSkip = false;
                    addErrMsg(errMsg, ITEM_USER + ":" + userId, ErrorCode.ERR_NOTFOUND);
                }
            }

            if (notSkip) {
                //"add" method
                if (apiType.equals(API_ADD)) {
                    if (isNewRecord(errMsg, userId, usersList)) {
                        usersList.add(userId);
                    } else {
                        addErrMsg(errMsg, ITEM_USER + ":" + userId, ErrorCode.ERR_ALREADYMEMBER);
                    }
                    //"remove" method
                } else if (apiType.equals(API_REMOVE)) {
                    if (!isNewRecord(errMsg, userId, usersList)) {
                        usersList.remove(userId);
                    } else {
                        addErrMsg(errMsg, ITEM_USER + ":" + userId, ErrorCode.ERR_NOTMEMBER);
                    }
                }
            }
        }
        return usersList;
    }

    /**
     * edit group's members(groups)
     * @param repositoryId TODO
     * @param groupsAry
     * @param errMsg
     * @param apiType
     * @param group
     * @return
     */
    private List<String> editGroupMembers(String repositoryId, JSONArray groupsAry, JSONArray errMsg,
            String apiType, Group group) { //check only when "add" API
        List<String> groupsList = new ArrayList<String>();

        List<String> gl = group.getGroups();
        if (gl != null)
            groupsList = gl;

        List<Group> allGroupsList = principalService.getGroups(repositoryId);
        List<String> allGroupsStringList = new ArrayList<String>();
        for (final Group g : allGroupsList) {
            allGroupsStringList.add(g.getId());
        }

        for (final Object obj : groupsAry) {
            JSONObject objJSON = (JSONObject) obj;
            String groupId = (String) objJSON.get(FORM_ID);
            boolean notSkip = true;

            //Existance check
            Group g = principalService.getGroupById(repositoryId, groupId);
            if (g == null && apiType.equals(API_ADD)) {
                notSkip = false;
                addErrMsg(errMsg, ITEM_GROUP + ":" + groupId, ErrorCode.ERR_NOTFOUND);
            }

            if (notSkip) {
                //"add" method
                if (apiType.equals(API_ADD)) {
                    if (isNewRecord(errMsg, groupId, groupsList)) {
                        if (groupId.equals(group.getId())) {
                            //skip and error when trying to add the group to itself
                            addErrMsg(errMsg, ITEM_GROUP, ErrorCode.ERR_GROUPITSELF);
                        } else {
                            groupsList.add(groupId);
                        }
                    } else {
                        //skip and message
                        addErrMsg(errMsg, ITEM_GROUP + ":" + groupId, ErrorCode.ERR_ALREADYMEMBER);
                    }
                    //"remove" method
                } else if (apiType.equals(API_REMOVE)) {
                    if (!isNewRecord(errMsg, groupId, groupsList)) {
                        groupsList.remove(groupId);
                    } else {
                        //skip
                        addErrMsg(errMsg, ITEM_GROUP + ":" + groupId, ErrorCode.ERR_NOTMEMBER);
                    }
                }
            }
        }
        return groupsList;
    }

    boolean validateNewGroup(String repositoryId, boolean status, JSONArray errMsg, String groupId, String name) {
        if (StringUtils.isBlank(groupId)) {
            status = false;
            addErrMsg(errMsg, ITEM_GROUPID, ErrorCode.ERR_MANDATORY);
        }
        //groupID uniqueness
        Group group = principalService.getGroupById(repositoryId, groupId);
        if (group != null) {
            status = false;
            addErrMsg(errMsg, ITEM_GROUPID, ErrorCode.ERR_ALREADYEXISTS);
        }

        if (StringUtils.isBlank(name)) {
            status = false;
            addErrMsg(errMsg, ITEM_GROUPNAME, ErrorCode.ERR_MANDATORY);
        }

        return status;
    }

    boolean validateGroup(boolean status, JSONArray errMsg, String groupId, String name) {
        if (StringUtils.isBlank(name)) {
            status = false;
            addErrMsg(errMsg, ITEM_GROUPNAME, ErrorCode.ERR_MANDATORY);
        }

        return status;
    }

    private JSONObject convertGroupToJson(Group group) {
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        String created = new String();
        try {
            created = sdf.format(group.getCreated().getTime());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        String modified = new String();
        try {
            modified = sdf.format(group.getModified().getTime());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        JSONObject groupJSON = new JSONObject();
        groupJSON.put(ITEM_GROUPID, group.getGroupId());
        groupJSON.put(ITEM_GROUPNAME, group.getName());
        groupJSON.put(ITEM_CREATOR, group.getCreator());
        groupJSON.put(ITEM_CREATED, created);
        groupJSON.put(ITEM_MODIFIER, group.getModifier());
        groupJSON.put(ITEM_MODIFIED, modified);
        groupJSON.put(ITEM_TYPE, group.getType());
        groupJSON.put(ITEM_MEMBER_USERS, group.getUsers());
        groupJSON.put(ITEM_MEMBER_USERSSIZE, group.getUsers().size());
        groupJSON.put(ITEM_MEMBER_GROUPS, group.getGroups());
        groupJSON.put(ITEM_MEMBER_GROUPSSIZE, group.getGroups().size());

        return groupJSON;
    }

    private JSONArray parseJsonArray(String str) {
        JSONParser parser = new JSONParser();
        Object obj;
        try {
            obj = parser.parse(str);
            JSONArray result = (JSONArray) obj;
            return result;
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return new JSONArray();
    }

    public void setPrincipalService(PrincipalService principalService) {
        this.principalService = principalService;
    }
}