package com.brframework.commoncms.utils; import com.brframework.commoncms.annatotion.Panel; import com.brframework.commoncms.annatotion.option.CmsOption; import com.brframework.commoncms.core.Option; import com.brframework.commoncms.core.UriProtocol; import com.brframework.commoncms.core.option.DefOption; import com.brframework.commoncms.core.uri.PanelUri; import com.brframework.commoncms.core.uri.RequestUri; import com.brframework.commonsecurity.core.SecurityContextHolder; import com.brframework.commonweb.exception.HandleException; import com.brframework.commonweb.json.PageParam; import com.brframework.commonweb.utils.ServletUtils; import com.google.common.base.Strings; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.brframework.commoncms.annatotion.LayoutColumn; import com.brframework.commoncms.core.layout.PanelLayoutColumn; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import org.apache.commons.lang3.StringUtils; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.HandlerMapping; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.List; import java.util.Map; /** * @author xu * @date 2018/10/15 15:26 */ public class ControllerUtil { private final static LocalVariableTableParameterNameDiscoverer LVTPND = new LocalVariableTableParameterNameDiscoverer(); /** * 获取一个类所有的字段 * @param c * @return */ public static List getAllField(Class c){ List fields = Lists.newArrayList(c.getDeclaredFields()); if(Object.class.getName().equals(c.getSuperclass().getName())){ return fields; } fields.addAll(getAllField(c.getSuperclass())); return fields; } /** * 解析方法uri协议 * @param method 解析的method * @param alert 如果是进行某个请求操作时的提示语 * @return */ public static UriProtocol parseMethodUriProtocol(Method method, String alert){ //获取Panel注解类型,用于判断方法的跳转意图 Panel panel = AnnotatedElementUtils.findMergedAnnotation(method, Panel.class); String protocol; String path; String requestMethod = ControllerUtil.getHttpMethod(method); String url = ControllerUtil.getControllerUrl(method); if (panel == null) { //如果不存在Panel相关注解,说明这是一个请求方法 protocol = UriProtocol.REQUEST; RequestUri requestUri = new RequestUri(); requestUri.setAlert(alert); requestUri.setBody(null); requestUri.setMethod(requestMethod); requestUri.setUrl(url); path = requestUri.toString(); } else { //如果存在Panel注解,则说明这是一个Panel模块 protocol = UriProtocol.PANEL; PanelUri panelUri = new PanelUri(); panelUri.setMethod(requestMethod); panelUri.setUrl(url); path = panelUri.toString(); } return UriProtocol.builder() .protocol(protocol) .path(path) .build(); } /** * 生成列 * * @param field * @return */ public static PanelLayoutColumn createColumn(Field field) throws Throwable { LayoutColumn cmsColumn = AnnotatedElementUtils.findMergedAnnotation(field, LayoutColumn.class); PanelLayoutColumn column; if (cmsColumn == null) { //默认列 column = LayoutColumnUtil.defaultColumn(field); } else { column = cmsColumn.type().newInstance(); } column.create(field); return column; } /** * 获取方法的参数,解决参数名为arg0, arg1的问题 * @param method * @return * @throws NoSuchFieldException * @throws IllegalAccessException */ public static Parameter[] getHandleParameter(Method method) throws NoSuchFieldException, IllegalAccessException { String[] parameterNames = LVTPND.getParameterNames(method); Parameter[] parameters = method.getParameters(); Field nameField = Parameter.class.getDeclaredField("name"); nameField.setAccessible(true); for (int i = 0; i < parameterNames.length; i++) { nameField.set(parameters[i], parameterNames[i]); } return parameters; } /** * 获取请求里的URI参数 * @param method * @return * @throws NoSuchFieldException * @throws IllegalAccessException */ public static Map getUriParameter(Method method) throws NoSuchFieldException, IllegalAccessException { Map uriParams = (Map) ServletUtils.request().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); Parameter[] parameters = ControllerUtil.getHandleParameter(method); Map uriParameter = Maps.newHashMap(); for (Parameter parameter : parameters) { PathVariable pathVariable = parameter.getAnnotation(PathVariable.class); if(pathVariable != null){ String name = pathVariable.value(); if(Strings.isNullOrEmpty(name)){ name = parameter.getName(); } uriParameter.put(name, uriParams.get(name).toString()); } } return uriParameter; } /** * 将包含有ApiModelProperty注解的字段筛选出来 * * @param oldFields * @return */ public static List handlerPropertyField(List oldFields) { List newFields = Lists.newArrayList(); for (Field oldField : oldFields) { ApiModelProperty apiModelProperty = AnnotationUtils.findAnnotation(oldField, ApiModelProperty.class); if (apiModelProperty != null) { newFields.add(oldField); } } return newFields; } /** * 获取方法参数里有ApiModel注解的类 * 自动忽略PageParam * * @param method * @return */ public static List getParamApiModelClass(Method method) { Class[] parameterTypes = method.getParameterTypes(); List apiTypes = Lists.newArrayList(); for (Class parameterType : parameterTypes) { if (parameterType.getDeclaredAnnotation(ApiModel.class) != null) { if (!parameterType.getName().equals(PageParam.class.getName())) { apiTypes.add(parameterType); } } } return apiTypes; } /** * 获取Controller完整的url * * @param method * @return */ public static String getControllerUrl(Method method) { //获取前缀 String prefix = getPrefixUrl(method); //获取请求地址 String url = getMappingUrl(method); if (!url.startsWith("/") && !prefix.endsWith("/")) { url = "/" + url; } if (url.startsWith("/") && prefix.endsWith("/")) { url = url.substring(1); } return prefix + url; } /** * 获取方法的前缀 * * @param method * @return */ public static String getPrefixUrl(Method method) { RequestMapping requestMapping = AnnotationUtils.findAnnotation(method.getDeclaringClass(), RequestMapping.class); String prefix = ""; if (requestMapping != null) { prefix = requestMapping.value()[0]; } return prefix; } /** * 获取标题 * * @param method * @return */ public static String getTitle(Method method) { ApiOperation ao = AnnotatedElementUtils.findMergedAnnotation(method, ApiOperation.class); if (ao == null) { throw new HandleException("方法" + method.toString() + "不存在ApiOperation注解"); } return ao.value(); } /** * 获取方法映射的url * * @param method * @return */ public static String getMappingUrl(Method method) { RequestMapping rm = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class); return rm.value()[0]; } /** * 获取HTTP METHOD * * @param method * @return */ public static String getHttpMethod(Method method) { RequestMapping rm = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class); if (rm.method().length == 0) { throw new HandleException("当前方法中不存在RequestMapping注解"); } return rm.method()[0].toString(); } /** * 方法上的Option是否有权限操作 * @return */ public static boolean hasMethodOptionRole(Method method, CmsOption option){ String role = ControllerUtil.getOptionRoleByMethod(method, option); if(StringUtils.isEmpty(role) || SecurityContextHolder.hasRole("ROLE_" + role)){ return true; } return false; } /** * 获取Option uriMappingMethod映射方法需要的权限 * @param method * @param option * @return */ public static String getOptionRoleByMethod(Method method, CmsOption option){ if(StringUtils.isEmpty(option.uriMappingMethod())){ return ""; } Method[] declaredMethods = method.getDeclaringClass().getMethods(); for (Method declaredMethod : declaredMethods) { if (declaredMethod.getName().equals(option.uriMappingMethod())) { PreAuthorize authAnn = AnnotationUtils.findAnnotation(declaredMethod, PreAuthorize.class); if(authAnn == null){ break; } return MenuPermissionUtils.getRoleName(authAnn.value()); } } return ""; } }