【JSF】Richfaces复选框树(Checkbox tree)的权限分配的解决方案
应大家要求,在此帖上效果图:
设计信息系统的时候,往往要设计一套用户管理模块,其中就会牵扯到角色权限的分配,在Richfaces中可以使用PickList来进行角色的分配,但权限的分配不好使用这个控件,因为权限有时候根据父子模块来分配,那么就要分级,而PickList不带分级功能,这时候我们就需要一个Checkbox tree来满足我们的需要。
Checkbox tree的页面代码:
<
rich:tree
switchType
="client"
value
="#{user.privilegeTree}"
var ="item" selectedClass ="selectedNode" >
< rich:treeNode highlightedClass ="treeLink" >
< h:selectBooleanCheckbox value ="#{item.selected}" >
</ h:selectBooleanCheckbox >
< h:outputText value ="#{item.name}" />
</ rich:treeNode >
</ rich:tree >
页面用到的js代码,(注意:如果页面中有其他的checkbox,这段代码需要进行修改):
var ="item" selectedClass ="selectedNode" >
< rich:treeNode highlightedClass ="treeLink" >
< h:selectBooleanCheckbox value ="#{item.selected}" >
</ h:selectBooleanCheckbox >
< h:outputText value ="#{item.name}" />
</ rich:treeNode >
</ rich:tree >
<
script type
=
"
text/javascript
"
src
=
"
<%=basePath%>pages/js/jquery.js
"
></
script
>
< script type = " text/javascript " >
jQuery.noConflict(); // 与JSF搭配需要这句话,不然会有冲突
jQuery(document).ready( function () {
// Add click event listener to each checkbox in the tree page
// Note! Using this simple selector assumes that there are no other
// checkboxes on the page, if there are other checkboxes then
// selector should be changed
jQuery(":checkbox").click(function(){
updateChildren(this);
});
} );
</ script >
< script type = " text/javascript " >
function updateChildren(currentCheckBox)
{
// Get state of current checkbox (true or false)
var state = currentCheckBox.checked;
// Get parent TABLE, where current checkbox is places
var parentTables = jQuery(currentCheckBox).parents("table");
var parentTable = parentTables[0];
// Get DIV where child nodes with checkboxes are situated
// See http://docs.jquery.com/Traversing/ to get better uderstanding of
// parents() and next()
var childDivs = jQuery(parentTable).next("div");
var childDiv = childDivs[0];
// Iterate over all child nodes checkboxes and set same state as the
// current checkbox state
jQuery(childDiv).contents().find(":checkbox").each(function() {
this.checked = state;
});
}
</ script >
这样页面部分就完成了,下面是后台处理的代码。
< script type = " text/javascript " >
jQuery.noConflict(); // 与JSF搭配需要这句话,不然会有冲突
jQuery(document).ready( function () {
// Add click event listener to each checkbox in the tree page
// Note! Using this simple selector assumes that there are no other
// checkboxes on the page, if there are other checkboxes then
// selector should be changed
jQuery(":checkbox").click(function(){
updateChildren(this);
});
} );
</ script >
< script type = " text/javascript " >
function updateChildren(currentCheckBox)
{
// Get state of current checkbox (true or false)
var state = currentCheckBox.checked;
// Get parent TABLE, where current checkbox is places
var parentTables = jQuery(currentCheckBox).parents("table");
var parentTable = parentTables[0];
// Get DIV where child nodes with checkboxes are situated
// See http://docs.jquery.com/Traversing/ to get better uderstanding of
// parents() and next()
var childDivs = jQuery(parentTable).next("div");
var childDiv = childDivs[0];
// Iterate over all child nodes checkboxes and set same state as the
// current checkbox state
jQuery(childDiv).contents().find(":checkbox").each(function() {
this.checked = state;
});
}
</ script >
User当中的代码:
public
PrivilegeTreeNode getPrivilegeTree()
{
try {
if ( privilegeTree == null )
privilegeTree = new PrivilegeTree();
return privilegeTree.getPrivilegeRootNode();
} catch (Exception e) {
info("获得权限树出错", e);
return null;
}
}
权限树代码:
{
try {
if ( privilegeTree == null )
privilegeTree = new PrivilegeTree();
return privilegeTree.getPrivilegeRootNode();
} catch (Exception e) {
info("获得权限树出错", e);
return null;
}
}
public
class
PrivilegeTree
{
private static int root = 0;//根节点的父编号
private PrivilegeTreeNode privilegeRootNode = null;
public PrivilegeTreeNode getPrivilegeRootNode()
{
if(privilegeRootNode == null)
{
privilegeRootNode = new PrivilegeTreeNode(root);
privilegeRootNode.setId(0);
privilegeRootNode.setName("角色权限");
}
return privilegeRootNode;
}
}
树节点的代码:
{
private static int root = 0;//根节点的父编号
private PrivilegeTreeNode privilegeRootNode = null;
public PrivilegeTreeNode getPrivilegeRootNode()
{
if(privilegeRootNode == null)
{
privilegeRootNode = new PrivilegeTreeNode(root);
privilegeRootNode.setId(0);
privilegeRootNode.setName("角色权限");
}
return privilegeRootNode;
}
}
public
class
PrivilegeTreeNode
implements
TreeNode
{
private int id;
private String name = null;
private TreeNode parent = null;
private Map children = new HashMap();;
private boolean selected = false;
private FuncModuleTreeDefDTO funcModuleTreeDefDTO = null;
public PrivilegeTreeNode(int parent)
{
List<FuncModuleTreeDefDTO> list = WSFactory.getUserManagementBODelegate().getFuncModuleTreeDefsByParentId(parent);
if(list != null)
{
for(FuncModuleTreeDefDTO obj : list)
{
int oId = obj.getFuncModuleTreeDef().getModuleid();
PrivilegeTreeNode node = new PrivilegeTreeNode(oId);
node.setParent(this);
node.setId(oId);
node.setName(obj.getFuncModuleTreeDef().getModuleName());
node.setFuncModuleTreeDefDTO(obj);
addChild(oId, node);
}
}
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#addChild(java.lang.Object, org.richfaces.model.TreeNode)
*/
public void addChild(Object key, TreeNode tn)
{
children.put(key, tn);
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#getChild(java.lang.Object)
*/
public TreeNode getChild(Object key)
{
// TODO Auto-generated method stub
if(children != null)
return (TreeNode)children.get(key);
return null;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#getChildren()
*/
public Iterator getChildren()
{
if(children != null)
return children.entrySet().iterator();
return null;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#getData()
*/
public Object getData()
{
// TODO Auto-generated method stub
return this;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#getParent()
*/
public TreeNode getParent()
{
return this.parent;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#isLeaf()
*/
public boolean isLeaf()
{
if(children == null || children.isEmpty())
return true;
return false;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#removeChild(java.lang.Object)
*/
public void removeChild(Object key)
{
if(children != null)
children.remove(key);
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#setData(java.lang.Object)
*/
public void setData(Object data)
{
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#setParent(org.richfaces.model.TreeNode)
*/
public void setParent(TreeNode parent)
{
// TODO Auto-generated method stub
this.parent = parent;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public boolean isSelected()
{
return selected;
}
public void setSelected(boolean selected)
{
this.selected = selected;
}
public void setChildren(Map children)
{
this.children = children;
}
public FuncModuleTreeDefDTO getFuncModuleTreeDefDTO()
{
return funcModuleTreeDefDTO;
}
public void setFuncModuleTreeDefDTO(FuncModuleTreeDefDTO funcModuleTreeDefDTO)
{
this.funcModuleTreeDefDTO = funcModuleTreeDefDTO;
}
}
User中,获取用户选定值得代码:
{
private int id;
private String name = null;
private TreeNode parent = null;
private Map children = new HashMap();;
private boolean selected = false;
private FuncModuleTreeDefDTO funcModuleTreeDefDTO = null;
public PrivilegeTreeNode(int parent)
{
List<FuncModuleTreeDefDTO> list = WSFactory.getUserManagementBODelegate().getFuncModuleTreeDefsByParentId(parent);
if(list != null)
{
for(FuncModuleTreeDefDTO obj : list)
{
int oId = obj.getFuncModuleTreeDef().getModuleid();
PrivilegeTreeNode node = new PrivilegeTreeNode(oId);
node.setParent(this);
node.setId(oId);
node.setName(obj.getFuncModuleTreeDef().getModuleName());
node.setFuncModuleTreeDefDTO(obj);
addChild(oId, node);
}
}
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#addChild(java.lang.Object, org.richfaces.model.TreeNode)
*/
public void addChild(Object key, TreeNode tn)
{
children.put(key, tn);
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#getChild(java.lang.Object)
*/
public TreeNode getChild(Object key)
{
// TODO Auto-generated method stub
if(children != null)
return (TreeNode)children.get(key);
return null;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#getChildren()
*/
public Iterator getChildren()
{
if(children != null)
return children.entrySet().iterator();
return null;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#getData()
*/
public Object getData()
{
// TODO Auto-generated method stub
return this;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#getParent()
*/
public TreeNode getParent()
{
return this.parent;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#isLeaf()
*/
public boolean isLeaf()
{
if(children == null || children.isEmpty())
return true;
return false;
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#removeChild(java.lang.Object)
*/
public void removeChild(Object key)
{
if(children != null)
children.remove(key);
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#setData(java.lang.Object)
*/
public void setData(Object data)
{
}
/**//* (non-Javadoc)
* @see org.richfaces.model.TreeNode#setParent(org.richfaces.model.TreeNode)
*/
public void setParent(TreeNode parent)
{
// TODO Auto-generated method stub
this.parent = parent;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public boolean isSelected()
{
return selected;
}
public void setSelected(boolean selected)
{
this.selected = selected;
}
public void setChildren(Map children)
{
this.children = children;
}
public FuncModuleTreeDefDTO getFuncModuleTreeDefDTO()
{
return funcModuleTreeDefDTO;
}
public void setFuncModuleTreeDefDTO(FuncModuleTreeDefDTO funcModuleTreeDefDTO)
{
this.funcModuleTreeDefDTO = funcModuleTreeDefDTO;
}
}
此为递归函数,需要在其他业务逻辑中调用
/** */
/**
* 获得所有被选择权限的列表
*
* @param list
* PrivRoleMainDefDTO的权限列表
* @param node
* 从哪个树获取
* @param gregorianCalendarDate
* 当前时间
* @param userid
* 当前用户id
* @param roleId
* 相关角色id
*/
private void getPrivRoleDetailDefDTOs(List < PrivRoleDetailDefDTO > list,
PrivilegeTreeNode node, XMLGregorianCalendar gregorianCalendarDate,
Integer userid, int roleId)
{
if ( node == null )
return;
try {
Iterator itr = node.getChildren();
while (itr.hasNext()) {
PrivilegeTreeNode childNode = (PrivilegeTreeNode) ((Entry)itr.next()).getValue();
if ( childNode.isSelected() ) {
PrivRoleDetailDef detail = new PrivRoleDetailDef();
FuncModuleTreeDef fm = childNode
.getFuncModuleTreeDefDTO().getFuncModuleTreeDef();
detail.setModuleid(fm.getModuleid());
detail.setLogOperAction(fm.getLogOperAction());
detail.setPrivType(1);
detail.setRecUpdateTime(gregorianCalendarDate);
detail.setRecUpdateUserid(userid);
detail.setRoleid(roleId);
PrivRoleDetailDefDTO dto = new PrivRoleDetailDefDTO();
dto.setPrivRoleDetailDef(detail);
list.add(dto);
info("Module Id: " + detail.getModuleid()+ ", Module Name: " + childNode.getName());
}
// 把子权限也添加进去
getPrivRoleDetailDefDTOs(list, childNode,
gregorianCalendarDate, userid, roleId);
}
} catch (Exception e) {
info("获得权限详细列表出错", e);
}
}
修改权限信息时,初始化权限树:
* 获得所有被选择权限的列表
*
* @param list
* PrivRoleMainDefDTO的权限列表
* @param node
* 从哪个树获取
* @param gregorianCalendarDate
* 当前时间
* @param userid
* 当前用户id
* @param roleId
* 相关角色id
*/
private void getPrivRoleDetailDefDTOs(List < PrivRoleDetailDefDTO > list,
PrivilegeTreeNode node, XMLGregorianCalendar gregorianCalendarDate,
Integer userid, int roleId)
{
if ( node == null )
return;
try {
Iterator itr = node.getChildren();
while (itr.hasNext()) {
PrivilegeTreeNode childNode = (PrivilegeTreeNode) ((Entry)itr.next()).getValue();
if ( childNode.isSelected() ) {
PrivRoleDetailDef detail = new PrivRoleDetailDef();
FuncModuleTreeDef fm = childNode
.getFuncModuleTreeDefDTO().getFuncModuleTreeDef();
detail.setModuleid(fm.getModuleid());
detail.setLogOperAction(fm.getLogOperAction());
detail.setPrivType(1);
detail.setRecUpdateTime(gregorianCalendarDate);
detail.setRecUpdateUserid(userid);
detail.setRoleid(roleId);
PrivRoleDetailDefDTO dto = new PrivRoleDetailDefDTO();
dto.setPrivRoleDetailDef(detail);
list.add(dto);
info("Module Id: " + detail.getModuleid()+ ", Module Name: " + childNode.getName());
}
// 把子权限也添加进去
getPrivRoleDetailDefDTOs(list, childNode,
gregorianCalendarDate, userid, roleId);
}
} catch (Exception e) {
info("获得权限详细列表出错", e);
}
}
/** */
/**
* 根据指定的值初始化权限树
* @param list 若指定该值,则用该列表初始化树的选择
* @param node 根树节点
* @param b 如没有指定list,则取本值初始化权限树
*/
private void initPrivilegeTree(List < PrivRoleDetailDefDTO > list,
PrivilegeTreeNode node, boolean b)
{
if ( node == null )
return;
try {
if(list == null)//如果没有指定列表
{
node.setSelected(b);
}else{//指定了列表之后
for(int i = 0; i< list.size(); i++)
{
PrivRoleDetailDef obj = ((PrivRoleDetailDefDTO)list.get(i)).getPrivRoleDetailDef();
if(obj.getModuleid().compareTo(new Integer(node.getId())) == 0)
{
//找到并移除当前列表里面的值
node.setSelected(true);
list.remove(i);
}
}
}
//初始化子节点
Iterator itr = node.getChildren();
while (itr.hasNext()) {
PrivilegeTreeNode childNode = (PrivilegeTreeNode) ((Entry)itr.next()).getValue();
initPrivilegeTree(list, childNode, b);
}
} catch (Exception e) {
info("获得权限详细列表出错", e);
}
}
同样也是一个递归函数,调用的时候需要注意。
* 根据指定的值初始化权限树
* @param list 若指定该值,则用该列表初始化树的选择
* @param node 根树节点
* @param b 如没有指定list,则取本值初始化权限树
*/
private void initPrivilegeTree(List < PrivRoleDetailDefDTO > list,
PrivilegeTreeNode node, boolean b)
{
if ( node == null )
return;
try {
if(list == null)//如果没有指定列表
{
node.setSelected(b);
}else{//指定了列表之后
for(int i = 0; i< list.size(); i++)
{
PrivRoleDetailDef obj = ((PrivRoleDetailDefDTO)list.get(i)).getPrivRoleDetailDef();
if(obj.getModuleid().compareTo(new Integer(node.getId())) == 0)
{
//找到并移除当前列表里面的值
node.setSelected(true);
list.remove(i);
}
}
}
//初始化子节点
Iterator itr = node.getChildren();
while (itr.hasNext()) {
PrivilegeTreeNode childNode = (PrivilegeTreeNode) ((Entry)itr.next()).getValue();
initPrivilegeTree(list, childNode, b);
}
} catch (Exception e) {
info("获得权限详细列表出错", e);
}
}
初始化权限树之前,需要拷贝一份list,因为我在初始化权限树的时候不断的从原有list中删除数据
List
<
PrivRoleDetailDefDTO
>
list
=
new
ArrayList
<
PrivRoleDetailDefDTO
>
(roleMain.getPrivRoleDetailDefDTOs().size());
for (Object obj : roleMain.getPrivRoleDetailDefDTOs().toArray())
{
list.add((PrivRoleDetailDefDTO)obj);
}
initPrivilegeTree(list, getPrivilegeTree(), false );
for (Object obj : roleMain.getPrivRoleDetailDefDTOs().toArray())
{
list.add((PrivRoleDetailDefDTO)obj);
}
initPrivilegeTree(list, getPrivilegeTree(), false );
至此,权限树的问题就解决了。。
---------------------------------------------------------
专注移动开发
Android, Windows Mobile, iPhone, J2ME, BlackBerry, Symbian