package com.norteksoft.mms.base.utils; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.proxy.HibernateProxy; import com.norteksoft.product.api.entity.Role; import com.norteksoft.product.api.entity.Department; import com.norteksoft.product.api.entity.Workgroup; import com.norteksoft.mms.authority.entity.Condition; import com.norteksoft.mms.authority.entity.PermissionItem; import com.norteksoft.mms.authority.enumeration.FieldOperator; import com.norteksoft.mms.authority.enumeration.UserOperator; import com.norteksoft.mms.form.enumeration.DataType; import com.norteksoft.product.api.ApiFactory; import com.norteksoft.product.util.BeanUtils; import com.norteksoft.wf.base.enumeration.LogicOperator; import com.norteksoft.wf.base.utils.BeanShellUtil; /** * 根据 PermissionItem 组合,判断当前用户是否满足条件 * @author xiao * 2012-11-2 */ public class PermissionUtils { protected static Log logger = LogFactory.getLog(PermissionUtils.class); public static boolean hasPermission(List<PermissionItem> items, UserInfo user){ //UserInfo user = new UserInfo(ContextUtils.getLoginName()); StringBuilder result = new StringBuilder(); for(PermissionItem item : items){ result.append(" ").append(itemPermission(item, user)).append(joinType(item.getJoinType())); } String express = result.substring(0, result.length()-2); return BeanShellUtil.evel(express); } private static boolean itemPermission(PermissionItem item, UserInfo user){ switch (item.getItemType()) { case USER: return permissionDecision(item.getOperator(), user.loginNames, item.getConditionValue()); case DEPARTMENT: if(user.departments == null){ user.departments = getDepartments(user.loginName); } return permissionDecision(item.getOperator(), user.departments, item.getConditionValue()); case ROLE: if(user.roles == null){ user.roles = getRoles(user.loginName); } return permissionDecision(item.getOperator(), user.roles, item.getConditionValue()); case WORKGROUP: if(user.workgroups == null){ user.workgroups = getWorkgroups(user.loginName); } return permissionDecision(item.getOperator(), user.workgroups, item.getConditionValue()); } return false; } private static boolean permissionDecision(UserOperator operator, List<String> src, String value){ switch (operator) { case ET: if(src.contains(value)) return true; break; case NET: if(!src.contains(value)) return true; break; } return false; } private static String joinType(LogicOperator type){ switch (type) { case AND: return " &&"; case OR: return " ||"; } return ""; } private static List<String> getRoles(String loginName){ Set<Role> roles = ApiFactory.getAcsService().getRolesByUser(loginName); List<String> result = new ArrayList<String>(); for(Role role : roles){ result.add(role.getCode()); } return result; } private static List<String> getWorkgroups(String loginName){ List<Workgroup> groups = ApiFactory.getAcsService().getWorkgroupsByUser(loginName); List<String> result = new ArrayList<String>(); for(Workgroup group : groups){ result.add(group.getId().toString()); } return result; } private static List<String> getDepartments(String loginName){ List<Department> depts = ApiFactory.getAcsService().getDepartments(loginName); List<String> result = new ArrayList<String>(); for(Department dept : depts){ result.add(dept.getId().toString()); } return result; } public static class UserInfo{ String loginName; List<String> loginNames = new ArrayList<String>(); List<String> roles; List<String> departments; List<String> workgroups; public UserInfo(String loginName){ this.loginName = loginName; this.loginNames.add(loginName); } } /** * 实体是否满足数据规则 * @param entity * @param rule */ public static boolean entityPermission(Object entity, List<Condition> conditions){ StringBuilder sb = new StringBuilder(); Object obj = null; Condition con =null; boolean result; try { for(int i=0;i<conditions.size();i++){ con = conditions.get(i); if(entity instanceof HibernateProxy){ HibernateProxy proxy = (HibernateProxy)entity; entity = proxy.getHibernateLazyInitializer().getImplementation(); } obj = BeanUtils.getFieldValue(entity, con.getField()); result = calculateCondition(obj, con.getOperator(), con.getDataType(), con.getConditionValue(),con.getEnumPath()); sb.append(result).append(joinType(con.getLgicOperator())); } } catch (Exception e) { logger.error("Compare value error. Field:[" + con.getField() + "], SRC: [" + obj + "], DEST:["+con.getConditionValue()+"]", e); } String express = sb.substring(0, sb.length()-2); return BeanShellUtil.evel(express); } /** * 计算表达式的值 * @param obj 原始值 * @param fo 比较符 * @param dt 数据类型 * @param value 比较的值 * @return */ public static boolean calculateCondition(Object obj, FieldOperator fo, DataType dt, String value,String enumPath){ switch (fo) { case IS_NULL: return obj == null; case NOT_NULL: return obj != null; case CONTAIN: if(dt==DataType.TEXT && obj!=null && value!=null){ return obj.toString().contains(value); } return false; case NOT_CONTAIN: if(dt==DataType.TEXT && obj!=null && value!=null){ return !obj.toString().contains(value); } return false; case ET: if(obj!=null && value!=null){ if(dt==DataType.ENUM){//处理枚举类型 return obj.equals(getValueByType(value, enumPath)); } if(dt==DataType.DATE){//处理日期类型 return ((Date)obj).getTime()==((Date)getValueByType(dt, value)).getTime(); } return obj.equals(getValueByType(dt, value)); } return false; case NET: if(obj!=null && value!=null){ return !obj.equals(getValueByType(dt, value)); } return false; case GT: if(comparableBigSmall(dt)){ return CompareUtils.compareGT(dt, obj, getValueByType(dt, value)); } return false; case GET: if(comparableBigSmall(dt)){ return CompareUtils.compareGET(dt, obj, getValueByType(dt, value)); } return false; case LT: if(comparableBigSmall(dt)){ return CompareUtils.compareLT(dt, obj, getValueByType(dt, value)); } return false; case LET: if(comparableBigSmall(dt)){ return CompareUtils.compareLET(dt, obj, getValueByType(dt, value)); } return false; } return false; } private static boolean comparableBigSmall(DataType dt){ return DataType.DATE==dt||DataType.TIME==dt||DataType.INTEGER==dt ||DataType.LONG==dt||DataType.DOUBLE==dt||DataType.FLOAT==dt; } public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); public static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); public static Object getValueByType(DataType dt, String value){ if(StringUtils.isEmpty(value)) return null; try { switch (dt) { case TEXT: return value; case DATE: return DATE_FORMAT.parse(value); case TIME: return TIME_FORMAT.parse(value); case INTEGER: return Integer.valueOf(value); case LONG: return Long.valueOf(value); case DOUBLE: return Double.valueOf(value); case FLOAT: return Float.valueOf(value); case BOOLEAN: return Boolean.valueOf(value); case ENUM: break; } } catch (Exception e) { logger.error("Parse string to " + dt + " error. string["+value+"]", e); } return null; } public static Object getValueByType( String value,String enumPath){ if(StringUtils.isEmpty(value)) return null; try { Object[] enumValues = Class.forName(enumPath).getEnumConstants(); for (Object object : enumValues) { if(object.toString().equals(value)){ return object; } } } catch (Exception e) { logger.error("Parse " + value + " to enum:"+enumPath+"error.", e); } return null; } }