001/** 002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.jboot.apidoc; 017 018import com.alibaba.fastjson.JSONObject; 019import com.alibaba.fastjson.parser.Feature; 020import com.jfinal.config.Routes; 021import com.jfinal.core.ActionKey; 022import com.jfinal.core.Path; 023import com.jfinal.kit.StrKit; 024import io.jboot.apidoc.annotation.ApiResp; 025import io.jboot.apidoc.annotation.ApiResps; 026import io.jboot.core.listener.JbootAppListener; 027import io.jboot.core.listener.JbootAppListenerManager; 028import io.jboot.utils.AnnotationUtil; 029import io.jboot.utils.StrUtil; 030import io.jboot.web.controller.annotation.*; 031 032import java.lang.reflect.Method; 033import java.util.*; 034 035public class ApiDocUtil { 036 037 038 public static String getControllerPath(Class<?> controllerClass) { 039 RequestMapping rm = controllerClass.getAnnotation(RequestMapping.class); 040 if (rm != null) { 041 return AnnotationUtil.get(rm.value()); 042 } 043 044 Path path = controllerClass.getAnnotation(Path.class); 045 if (path != null) { 046 return AnnotationUtil.get(path.value()); 047 } 048 049 PostMapping pm = controllerClass.getAnnotation(PostMapping.class); 050 if (pm != null) { 051 return AnnotationUtil.get(pm.value()); 052 } 053 054 GetMapping gm = controllerClass.getAnnotation(GetMapping.class); 055 if (gm != null) { 056 return AnnotationUtil.get(gm.value()); 057 } 058 059 060 return tryToGetInAppListener(controllerClass); 061 } 062 063 private static Map<Class<?>, String> controllerPathMap = null; 064 065 private static String tryToGetInAppListener(Class<?> controllerClass) { 066 067 if (controllerPathMap != null) { 068 return controllerPathMap.get(controllerClass); 069 } else { 070 controllerPathMap = new HashMap<>(); 071 } 072 073 List<JbootAppListener> listeners = JbootAppListenerManager.me().getListeners(); 074 if (listeners == null || listeners.isEmpty()) { 075 return null; 076 } 077 078 079 Routes baseRoutes = new Routes() { 080 @Override 081 public void config() { 082 } 083 084 @Override 085 public Routes add(Routes childRoutes) { 086 childRoutes.config(); 087 //all child routes 088 childRoutes.getRouteItemList() 089 .forEach(route -> controllerPathMap.put(route.getControllerClass(), route.getControllerPath())); 090 return this; 091 } 092 }; 093 094 listeners.forEach(jbootAppListener -> jbootAppListener.onRouteConfig(baseRoutes)); 095 096 //base Routes 097 baseRoutes.getRouteItemList().forEach(route -> controllerPathMap.put(route.getControllerClass(), route.getControllerPath())); 098 099 return controllerPathMap.get(controllerClass); 100 } 101 102 103 public static HttpMethod getControllerMethod(Class<?> controllerClass) { 104 RequestMapping rm = controllerClass.getAnnotation(RequestMapping.class); 105 if (rm != null) { 106 return HttpMethod.ALL; 107 } 108 109 Path path = controllerClass.getAnnotation(Path.class); 110 if (path != null) { 111 return HttpMethod.ALL; 112 } 113 114 PostMapping pm = controllerClass.getAnnotation(PostMapping.class); 115 if (pm != null) { 116 return HttpMethod.POST; 117 } 118 119 GetMapping gm = controllerClass.getAnnotation(GetMapping.class); 120 if (gm != null) { 121 return HttpMethod.GET; 122 } 123 return HttpMethod.ALL; 124 } 125 126 127 public static HttpMethod[] getMethodHttpMethods(Method method, HttpMethod defaultMethod) { 128 Set<HttpMethod> httpMethods = new HashSet<>(); 129 if (method.getAnnotation(GetRequest.class) != null) { 130 httpMethods.add(HttpMethod.GET); 131 } 132 if (method.getAnnotation(PostRequest.class) != null) { 133 httpMethods.add(HttpMethod.POST); 134 } 135 if (method.getAnnotation(PutRequest.class) != null) { 136 httpMethods.add(HttpMethod.PUT); 137 } 138 if (method.getAnnotation(DeleteRequest.class) != null) { 139 httpMethods.add(HttpMethod.DELETE); 140 } 141 if (method.getAnnotation(PatchRequest.class) != null) { 142 httpMethods.add(HttpMethod.PATCH); 143 } 144 return httpMethods.isEmpty() ? new HttpMethod[]{defaultMethod} : httpMethods.toArray(new HttpMethod[]{}); 145 } 146 147 148 private static final String SLASH = "/"; 149 150 public static String getActionKey(Method method, String controllerPath) { 151 String methodName = method.getName(); 152 ActionKey ak = method.getAnnotation(ActionKey.class); 153 String actionKey; 154 if (ak != null) { 155 actionKey = ak.value().trim(); 156 157 if (actionKey.startsWith(SLASH)) { 158 //actionKey = actionKey 159 } else if (actionKey.startsWith("./")) { 160 actionKey = controllerPath + actionKey.substring(1); 161 } else { 162 actionKey = SLASH + actionKey; 163 } 164 } else if (methodName.equals("index")) { 165 actionKey = controllerPath; 166 } else { 167 actionKey = controllerPath.equals(SLASH) ? SLASH + methodName : controllerPath + SLASH + methodName; 168 } 169 170 return actionKey; 171 } 172 173 174 public static List<ApiResponse> getApiResponseInMethod(Method method) { 175 176 List<ApiResponse> retList = new LinkedList<>(); 177 178 ApiResps apiResps = method.getAnnotation(ApiResps.class); 179 if (apiResps != null) { 180 for (ApiResp apiResp : apiResps.value()) { 181 retList.add(new ApiResponse(apiResp)); 182 } 183 } 184 185 ApiResp apiResp = method.getAnnotation(ApiResp.class); 186 if (apiResp != null) { 187 retList.add(new ApiResponse(apiResp)); 188 } 189 190 return retList; 191 } 192 193 194 public static String prettyJson(String json) { 195 if (StrUtil.isBlank(json)) { 196 return json; 197 } 198 JSONObject jsonObject = null; 199 try { 200 jsonObject = JSONObject.parseObject(json, Feature.OrderedField); 201 } catch (Exception e) { 202 return json; 203 } 204 return JSONObject.toJSONString(jsonObject, true); 205 } 206 207 208 public static String getterMethod2Field(Method getterMethod) { 209 String methodName = getterMethod.getName(); 210 if (methodName.startsWith("get") && methodName.length() > 3) { 211 return StrKit.firstCharToLowerCase(methodName.substring(3)); 212 } else if (methodName.startsWith("is") && methodName.length() > 2) { 213 return StrKit.firstCharToLowerCase(methodName.substring(2)); 214 } 215 return null; 216 } 217 218 219}