项目开始根据权限系统来控制目录和按钮了,为了读取和控制方便,需要把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}}
恩,到此,记录完成。
欢迎大家品论,发现目前为止都是浏览,没有品论的。很郁闷。。!