cn.guoyukun.spring.jpa.plugin.web.controller.BaseTreeableController.java Source code

Java tutorial

Introduction

Here is the source code for cn.guoyukun.spring.jpa.plugin.web.controller.BaseTreeableController.java

Source

/**
 * Copyright (c) 2005-2012 https://github.com/zhangkaitao
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package cn.guoyukun.spring.jpa.plugin.web.controller;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import cn.guoyukun.spring.jpa.Constants;
import cn.guoyukun.spring.jpa.entity.AbstractEntity;
import cn.guoyukun.spring.jpa.entity.enums.BooleanEnum;
import cn.guoyukun.spring.jpa.entity.search.SearchOperator;
import cn.guoyukun.spring.jpa.entity.search.Searchable;
import cn.guoyukun.spring.jpa.plugin.entity.Treeable;
import cn.guoyukun.spring.jpa.plugin.serivce.BaseTreeableService;
import cn.guoyukun.spring.jpa.plugin.web.controller.entity.ZTree;
import cn.guoyukun.spring.jpa.web.bind.annotation.PageableDefaults;
import cn.guoyukun.spring.web.controller.BaseController;
import cn.guoyukun.spring.web.controller.permission.PermissionList;

import com.google.common.collect.Lists;

/**
 * <p>User: 
 * <p>Date: 13-2-22 ?4:15
 * <p>Version: 1.0
 */
public abstract class BaseTreeableController<M extends AbstractEntity<ID> & Treeable<ID>, ID extends Serializable>
        extends BaseController<M, ID> {

    protected BaseTreeableService<M, ID> baseService;

    protected PermissionList permissionList = null;

    @Autowired
    public void setBaseService(BaseTreeableService<M, ID> baseService) {
        this.baseService = baseService;
    }

    /**
     * ???sys:user
     * ??? sys:user:create
     */
    public void setResourceIdentity(String resourceIdentity) {
        if (!StringUtils.isEmpty(resourceIdentity)) {
            permissionList = PermissionList.newPermissionList(resourceIdentity);
        }
    }

    protected void setCommonData(Model model) {
        model.addAttribute("booleanList", BooleanEnum.values());
    }

    @RequestMapping(value = { "", "main" }, method = RequestMethod.GET)
    public String main() {

        if (permissionList != null) {
            permissionList.assertHasViewPermission();
        }

        return viewName("main");
    }

    @RequestMapping(value = "tree", method = RequestMethod.GET)
    @PageableDefaults(sort = { "parentIds=asc", "weight=asc" })
    public String tree(HttpServletRequest request,
            @RequestParam(value = "searchName", required = false) String searchName,
            @RequestParam(value = "async", required = false, defaultValue = "false") boolean async,
            Searchable searchable, Model model) {

        if (permissionList != null) {
            permissionList.assertHasViewPermission();
        }

        List<M> models = null;

        if (!StringUtils.isEmpty(searchName)) {
            searchable.addSearchParam("name_like", searchName);
            models = baseService.findAllByName(searchable, null);
            if (!async) { //? ??
                searchable.removeSearchFilter("name_like");
                List<M> children = baseService.findChildren(models, searchable);
                models.removeAll(children);
                models.addAll(children);
            } else { //??

            }
        } else {
            if (!async) { //? ??
                models = baseService.findAllWithSort(searchable);
            } else { //??  
                models = baseService.findRootAndChild(searchable);
            }
        }

        model.addAttribute("trees", convertToZtreeList(request.getContextPath(), models, async, true));

        return viewName("tree");
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String view(@PathVariable("id") M m, Model model) {
        if (permissionList != null) {
            permissionList.assertHasViewPermission();
        }

        setCommonData(model);
        model.addAttribute("m", m);
        model.addAttribute(Constants.OP_NAME, "");
        return viewName("editForm");
    }

    @RequestMapping(value = "{id}/update", method = RequestMethod.GET)
    public String updateForm(@PathVariable("id") M m, Model model, RedirectAttributes redirectAttributes) {

        if (permissionList != null) {
            permissionList.assertHasUpdatePermission();
        }

        if (m == null) {
            redirectAttributes.addFlashAttribute(Constants.ERROR, "???");
            return redirectToUrl(viewName("success"));
        }

        setCommonData(model);
        model.addAttribute("m", m);
        model.addAttribute(Constants.OP_NAME, "");
        return viewName("editForm");
    }

    @RequestMapping(value = "{id}/update", method = RequestMethod.POST)
    public String update(Model model, @ModelAttribute("m") M m, BindingResult result,
            RedirectAttributes redirectAttributes) {

        if (permissionList != null) {
            permissionList.assertHasUpdatePermission();
        }

        if (result.hasErrors()) {
            return updateForm(m, model, redirectAttributes);
        }

        baseService.update(m);
        redirectAttributes.addFlashAttribute(Constants.MESSAGE, "?");
        return redirectToUrl(viewName("success"));
    }

    @RequestMapping(value = "{id}/delete", method = RequestMethod.GET)
    public String deleteForm(@PathVariable("id") M m, Model model) {

        if (permissionList != null) {
            permissionList.assertHasDeletePermission();
        }

        setCommonData(model);
        model.addAttribute("m", m);
        model.addAttribute(Constants.OP_NAME, "");
        return viewName("editForm");
    }

    @RequestMapping(value = "{id}/delete", method = RequestMethod.POST)
    public String deleteSelfAndChildren(Model model, @ModelAttribute("m") M m, BindingResult result,
            RedirectAttributes redirectAttributes) {

        if (permissionList != null) {
            permissionList.assertHasDeletePermission();
        }

        if (m.isRoot()) {
            result.reject("???");
            return deleteForm(m, model);
        }

        baseService.deleteSelfAndChild(m);
        redirectAttributes.addFlashAttribute(Constants.MESSAGE, "?");
        return redirectToUrl(viewName("success"));
    }

    @RequestMapping(value = "batch/delete")
    public String deleteInBatch(@RequestParam(value = "ids", required = false) ID[] ids,
            @RequestParam(value = Constants.BACK_URL, required = false) String backURL,
            RedirectAttributes redirectAttributes) {

        if (permissionList != null) {
            permissionList.assertHasDeletePermission();
        }

        //?? ? ???
        Searchable searchable = Searchable.newSearchable().addSearchFilter("id", SearchOperator.in, ids);
        List<M> mList = baseService.findAllWithNoPageNoSort(searchable);
        for (M m : mList) {
            if (m.isRoot()) {
                redirectAttributes.addFlashAttribute(Constants.ERROR,
                        "???");
                return redirectToUrl(backURL);
            }
        }

        baseService.deleteSelfAndChild(mList);
        redirectAttributes.addFlashAttribute(Constants.MESSAGE, "?");
        return redirectToUrl(backURL);
    }

    @RequestMapping(value = "{parent}/appendChild", method = RequestMethod.GET)
    public String appendChildForm(@PathVariable("parent") M parent, Model model) {

        if (permissionList != null) {
            permissionList.assertHasCreatePermission();
        }

        setCommonData(model);
        if (!model.containsAttribute("child")) {
            model.addAttribute("child", newModel());
        }

        model.addAttribute(Constants.OP_NAME, "?");

        return viewName("appendChildForm");
    }

    @RequestMapping(value = "{parent}/appendChild", method = RequestMethod.POST)
    public String appendChild(Model model, @PathVariable("parent") M parent, @ModelAttribute("child") M child,
            BindingResult result, RedirectAttributes redirectAttributes) {

        if (permissionList != null) {
            permissionList.assertHasCreatePermission();
        }

        setCommonData(model);

        if (result.hasErrors()) {
            return appendChildForm(parent, model);
        }

        baseService.appendChild(parent, child);

        redirectAttributes.addFlashAttribute(Constants.MESSAGE, "??");
        return redirectToUrl(viewName("success"));
    }

    @RequestMapping(value = "{source}/move", method = RequestMethod.GET)
    @PageableDefaults(sort = { "parentIds=asc", "weight=asc" })
    public String showMoveForm(HttpServletRequest request,
            @RequestParam(value = "async", required = false, defaultValue = "false") boolean async,
            @PathVariable("source") M source, Searchable searchable, Model model) {

        if (this.permissionList != null) {
            this.permissionList.assertHasEditPermission();
        }

        List<M> models = null;

        //???
        searchable.addSearchFilter("id", SearchOperator.ne, source.getId());
        searchable.addSearchFilter("parentIds", SearchOperator.notLike, source.makeSelfAsNewParentIds() + "%");

        if (!async) {
            models = baseService.findAllWithSort(searchable);
        } else {
            models = baseService.findRootAndChild(searchable);
        }

        model.addAttribute("trees", convertToZtreeList(request.getContextPath(), models, async, true));

        model.addAttribute(Constants.OP_NAME, "");

        return viewName("moveForm");
    }

    @RequestMapping(value = "{source}/move", method = RequestMethod.POST)
    @PageableDefaults(sort = { "parentIds=asc", "weight=asc" })
    public String move(HttpServletRequest request,
            @RequestParam(value = "async", required = false, defaultValue = "false") boolean async,
            @PathVariable("source") M source, @RequestParam("target") M target,
            @RequestParam("moveType") String moveType, Searchable searchable, Model model,
            RedirectAttributes redirectAttributes) {

        if (this.permissionList != null) {
            this.permissionList.assertHasEditPermission();
        }

        if (target.isRoot() && !moveType.equals("inner")) {
            model.addAttribute(Constants.ERROR, "???");
            return showMoveForm(request, async, source, searchable, model);
        }

        baseService.move(source, target, moveType);

        redirectAttributes.addFlashAttribute(Constants.MESSAGE, "?");
        return redirectToUrl(viewName("success"));
    }

    @RequestMapping(value = "{parent}/children", method = RequestMethod.GET)
    @PageableDefaults(sort = { "parentIds=asc", "weight=asc" })
    public String list(HttpServletRequest request, @PathVariable("parent") M parent, Searchable searchable,
            Model model) throws UnsupportedEncodingException {

        if (permissionList != null) {
            permissionList.assertHasViewPermission();
        }

        if (parent != null) {
            searchable.addSearchFilter("parentId", SearchOperator.eq, parent.getId());
        }

        model.addAttribute("page", baseService.findAll(searchable));

        return viewName("listChildren");
    }

    /**
     * ?
     *
     * @param searchable
     * @param model
     * @return
     */
    @RequestMapping(value = "{parent}/children", headers = "table=true", method = RequestMethod.GET)
    @PageableDefaults(sort = { "parentIds=asc", "weight=asc" })
    public String listTable(HttpServletRequest request, @PathVariable("parent") M parent, Searchable searchable,
            Model model) throws UnsupportedEncodingException {

        list(request, parent, searchable, model);
        return viewName("listChildrenTable");

    }

    /////////////////////////////////////ajax///////////////////////////////////////////////

    @RequestMapping(value = "ajax/load")
    @PageableDefaults(sort = { "parentIds=asc", "weight=asc" })
    @ResponseBody
    public Object load(HttpServletRequest request,
            @RequestParam(value = "async", defaultValue = "true") boolean async,
            @RequestParam(value = "asyncLoadAll", defaultValue = "false") boolean asyncLoadAll,
            @RequestParam(value = "searchName", required = false) String searchName,
            @RequestParam(value = "id", required = false) ID parentId,
            @RequestParam(value = "excludeId", required = false) ID excludeId,
            @RequestParam(value = "onlyCheckLeaf", required = false, defaultValue = "false") boolean onlyCheckLeaf,
            Searchable searchable) {

        M excludeM = baseService.findOne(excludeId);

        List<M> models = null;

        if (!StringUtils.isEmpty(searchName)) {//name
            searchable.addSearchParam("name_like", searchName);
            models = baseService.findAllByName(searchable, excludeM);
            if (!async || asyncLoadAll) {//?? ??? 
                searchable.removeSearchFilter("name_like");
                List<M> children = baseService.findChildren(models, searchable);
                models.removeAll(children);
                models.addAll(children);
            } else { //? ??

            }
        } else { //?parentId

            if (parentId != null) { //?? 
                searchable.addSearchFilter("parentId", SearchOperator.eq, parentId);
            }

            if (async && !asyncLoadAll) { //? ?
                // ? ??
                baseService.addExcludeSearchFilter(searchable, excludeM);

            }

            if (parentId == null && !asyncLoadAll) {
                models = baseService.findRootAndChild(searchable);
            } else {
                models = baseService.findAllWithSort(searchable);
            }
        }

        return convertToZtreeList(request.getContextPath(), models, async && !asyncLoadAll && parentId != null,
                onlyCheckLeaf);
    }

    @RequestMapping(value = "ajax/{parent}/appendChild", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public Object ajaxAppendChild(HttpServletRequest request, @PathVariable("parent") M parent) {

        if (permissionList != null) {
            permissionList.assertHasCreatePermission();
        }

        M child = newChild(parent);
        baseService.appendChild(parent, child);
        return convertToZtree(child, true, true);
    }

    protected M newChild(M parent) {
        M child = newModel();
        child.setName("");
        return child;
    }

    @RequestMapping(value = "ajax/{id}/delete", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public Object ajaxDeleteSelfAndChildren(@PathVariable("id") ID id) {

        if (this.permissionList != null) {
            this.permissionList.assertHasEditPermission();
        }

        M tree = baseService.findOne(id);
        baseService.deleteSelfAndChild(tree);
        return tree;
    }

    @RequestMapping(value = "ajax/{id}/rename", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public Object ajaxRename(HttpServletRequest request, @PathVariable("id") M tree,
            @RequestParam("newName") String newName) {

        if (permissionList != null) {
            permissionList.assertHasUpdatePermission();
        }

        tree.setName(newName);
        baseService.update(tree);
        return convertToZtree(tree, true, true);
    }

    @RequestMapping(value = "ajax/{sourceId}/{targetId}/{moveType}/move", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public Object ajaxMove(@PathVariable("sourceId") M source, @PathVariable("targetId") M target,
            @PathVariable("moveType") String moveType) {

        if (this.permissionList != null) {
            this.permissionList.assertHasEditPermission();
        }

        baseService.move(source, target, moveType);

        return source;
    }

    @RequestMapping("ajax/autocomplete")
    @PageableDefaults(value = 30)
    @ResponseBody
    public Set<String> autocomplete(Searchable searchable, @RequestParam("term") String term,
            @RequestParam(value = "excludeId", required = false) ID excludeId) {

        return baseService.findNames(searchable, term, excludeId);
    }

    @RequestMapping(value = "success")
    public String success() {
        return viewName("success");
    }

    @Override
    protected String redirectToUrl(String backURL) {
        if (!StringUtils.isEmpty(backURL)) {
            return super.redirectToUrl(backURL);
        }
        return super.redirectToUrl(viewName("success"));
    }

    private List<ZTree<ID>> convertToZtreeList(String contextPath, List<M> models, boolean async,
            boolean onlySelectLeaf) {
        List<ZTree<ID>> zTrees = Lists.newArrayList();

        if (models == null || models.isEmpty()) {
            return zTrees;
        }

        for (M m : models) {
            ZTree<ID> zTree = convertToZtree(m, !async, onlySelectLeaf);
            zTrees.add(zTree);
        }
        return zTrees;
    }

    protected ZTree<ID> convertToZtree(M m, boolean open, boolean onlyCheckLeaf) {
        ZTree<ID> zTree = new ZTree<ID>();
        zTree.setId(m.getId());
        zTree.setpId(m.getParentId());
        zTree.setName(m.getName());
        zTree.setIconSkin(m.getIcon());
        zTree.setOpen(open);
        zTree.setRoot(m.isRoot());
        zTree.setIsParent(m.isHasChildren());

        if (onlyCheckLeaf && zTree.isIsParent()) {
            zTree.setNocheck(true);
        } else {
            zTree.setNocheck(false);
        }

        return zTree;
    }

}