项目开始根据权限系统来控制目录和按钮了,为了读取和控制方便,需要把set里的权限列表变成map结构,用key来读取方便,很久以前做过个类似的,不过那时刚刚学习java,代码没有保留下来,所以这次记录下,以备日后查看。
关键代码和配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="cn.lh.posco.entity.management">
<class name="Role" table="t_roles" mutable="true">
<id name="id" column="ID" type="long">
<generator class="native" />
</id>
<property name="system" column="System" type="boolean" />
<property name="name" column="Name" type="string" />
<property name="remark" column="Remark" type="text" />
<set name="limits" fetch="join" cascade="all">
<key column="Role_ID" />
<one-to-many class="RoleLimit" />
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="cn.lh.posco.entity.management">
<class name="RoleLimit" table="t_role_limits">
<composite-id name="id" class="cn.lh.posco.entity.component.RoleLimitID">
<key-many-to-one name="role" class="Role" column="Role_ID" />
<key-many-to-one name="model" class="cn.lh.posco.entity.system.Model" column="Model_ID" />
<key-many-to-one name="method" class="cn.lh.posco.entity.system.Method" column="Method_ID" />
</composite-id>
<property name="enable" column="Enable" type="boolean"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="cn.lh.posco.entity.management">
<class name="Supervisor" table="t_supervisors">
<id name="id" column="ID" type="long">
<generator class="native" />
</id>
<property name="enable" column="Enable" type="boolean" />
<property name="name" column="Name" type="string" />
<property name="username" column="Username" type="string" />
<property name="password" column="Password" type="string" />
<property name="remark" column="Remark" type="text" />
<many-to-one name="role" column="Role_ID" class="Role" fetch="join" />
</class>
</hibernate-mapping>
supervisor , role和rolelimit ,还有Model和method两个实体:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="cn.lh.posco.entity.system">
<class name="Model" table="t_models" mutable="false">
<cache usage="read-only"/>
<id name="id" column="ID" type="long">
<generator class="native" />
</id>
<property name="menuable" column="MenuAble" type="boolean" />
<property name="name" column="Name" type="string" />
<property name="remark" column="Remark" type="text" />
<many-to-one name="parent" column="Parent_ID" class="Model" fetch="join" />
<set name="children" fetch="join" mutable="false">
<cache usage="read-only"/>
<key column="Parent_ID" />
<one-to-many class="Model" />
</set>
<set name="methods" table="t_model_methods" fetch="join" mutable="false">
<cache usage="read-only"/>
<key column="Model_ID" />
<many-to-many class="Method" column="Method_ID"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="cn.lh.posco.entity.system">
<class name="Method" table="t_methods" mutable="false">
<cache usage="read-only"/>
<id name="id" column="ID" type="long">
<generator class="native" />
</id>
<property name="menuable" column="MenuAble" type="boolean" />
<property name="name" column="Name" type="string" />
<property name="remark" column="Remark" type="text" />
<set name="models" table="t_model_methods" fetch="join" mutable="false">
<cache usage="read-only"/>
<key column="Method_ID" />
<many-to-many class="Model" column="Model_ID"/>
</set>
</class>
</hibernate-mapping>
这些就是hbm文件了,可以看到,model是这个自连树的结构,可以有parent,也可以有children,以前的文章提到过hibernate双向关联时,hashcode和equals方法里不能出现双向关联的字段,原因是会无限递归,还有toString也是。
然后,根据项目,觉得变成Map<String , Map<String, Boolean>>,这样的结构比较容易使用,第一个String是TopMdel的name,第二个就是路径,Boolean就是是否有权限
实现算法:
public void convertLimit2Map(Role role) {
Set<RoleLimit> limits = role.getLimits();
Set<Model> topModels = getTopModels(limits);
Map<String , Map<String, Boolean>> limitMap = convertLimitMap(topModels , limits);
ActionContext.getContext().getSession().put(Global.LONGIN_LIMITMAP, limitMap);
}
private Map<String, Map<String, Boolean>> convertLimitMap(Set<Model> topModels, Set<RoleLimit> limits) {
Map<String, Map<String, Boolean>> limitMap = new HashMap<String, Map<String,Boolean>>();
for(Model topModel : topModels){
String name = topModel.getName();
Map<String, Boolean> methodMap = new HashMap<String, Boolean>();
for(RoleLimit limit : limits){
RoleLimitID id = limit.getId();
Model model = id.getModel();
Method method = id.getMethod();
Boolean flag = Boolean.FALSE;
if(limit.getEnable()!=null && limit.getEnable()){
flag = Boolean.TRUE;
}
if(model.getTopModel().equals(topModel)){
String path = getPathFormModelAndMethod(model , method);
methodMap.put(path, flag);
}
}
limitMap.put(name, methodMap);
}
return limitMap;
}
private String getPathFormModelAndMethod(Model model, Method method) {
StringBuilder path = new StringBuilder();
String modelPath = model.toPath();
String methodName = method.getName();
path.append(modelPath+methodName);
return path.toString();
}
Model 的 toPath 和getTopModel 方法:
public String toPath(){
StringBuilder path = new StringBuilder();
List<String> list = new ArrayList<String>();
Model parent = getParent();
list.add(this.getName());
while(parent != null){
list.add(parent.getName());
parent = parent.getParent();
}
Collections.reverse(list);
for(String str : list){
path.append(str + IOUtils.DIR_SEPARATOR_UNIX);
}
return path.toString();
}
public Model getTopModel(){
if(isTopModel()){
return this ;
}
else{
Model parent = getParent();
while(!parent.isTopModel()){
parent = parent.getParent();
}
return parent ;
}
}
public Boolean isTopModel(){
return getParent() == null ;
}
恩,想法很简单的算法都是,就是先把TopModel都取出来,放到set里去重复,然后遍历每个TopModel的权限,做成上面说的那个map结构。
运行有一点小问题,就是空Map,这个在下一篇文章会阐述原因,这里先贴上解决后的结果:
{information={information/contact/search=true, information/produce/search=true, information/contact/modify=true, information/product/detile=true, information/news/create=true, information/company/detile=true, information/company/create=true, information/professional/detile=true, information/produce/detile=true, information/professional/create=true, information/news/detile=true, information/company/modify=true, information/professional/remove=true, information/company/search=true, information/product/modify=true, information/contact/create=true, information/product/create=true, information/news/modify=true, information/produce/remove=true, information/product/remove=true, information/professional/modify=true, information/contact/remove=true, information/news/search=true, information/professional/search=true, information/news/remove=true, information/contact/detile=true, information/produce/create=true, information/product/search=true, information/company/remove=true, information/produce/modify=true}, menu={menu/modify=true, menu/remove=true, menu/detile=true, menu/create=true, menu/search=true}, recruitment={recruitment/resume/create=true, recruitment/resume/search=true, recruitment/personnel/search=true, recruitment/job/detile=true, recruitment/job/modify=true, recruitment/resume/detile=true, recruitment/personnel/detile=true, recruitment/resume/remove=true, recruitment/job/create=true, recruitment/personnel/modify=true, recruitment/personnel/create=true, recruitment/resume/modify=true, recruitment/job/remove=true, recruitment/personnel/remove=true, recruitment/job/search=true}, management={management/supervior/detile=true, management/supervior/modify=true, management/supervior/remove=true, management/role/detile=true, management/role/remove=true, management/role/search=true, management/role/modify=true, management/role/create=true, management/supervior/search=true, management/supervior/create=true}, consult={consult/message/detile=true, consult/message/search=true, consult/reply/search=true, consult/message/create=true, consult/message/remove=true, consult/reply/remove=true, consult/message/modify=true, consult/reply/detile=true, consult/reply/modify=true, consult/reply/create=true}}
恩,到此,记录完成。
欢迎大家品论,发现目前为止都是浏览,没有品论的。很郁闷。。!