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 io.jboot.aop.annotation.DefaultValue; 019import io.jboot.apidoc.annotation.ApiPara; 020import io.jboot.apidoc.annotation.ApiParas; 021import io.jboot.utils.ClassType; 022import io.jboot.utils.ClassUtil; 023import io.jboot.web.json.JsonBody; 024 025import javax.validation.constraints.*; 026import java.io.Serializable; 027import java.lang.reflect.Method; 028import java.lang.reflect.Parameter; 029import java.lang.reflect.Type; 030import java.util.LinkedList; 031import java.util.List; 032import java.util.Map; 033 034public class ApiOperation implements Serializable { 035 036 private String value; //标题 037 private String notes; //描述 038 private String paraNotes; //参数描述,对所有参数的描述 039 private int orderNo; //排序序号 040 041 private String actionKey; // 路径 042 private ContentType contentType; 043 private List<ApiParameter> apiParameters; //所有的参数 044 045 private ClassType retType; //响应类型 046 private String retMockJson; //响应 mock json 047 private Map<String, List<ApiResponse>> retRemarks; //响应的字段备注(描述),key 类名的简称,value 类名的字段 048 049 050 private Class<?> controllerClass; //所在的类 051 private Method method; //对应的方法 052 053 054 public ApiOperation() { 055 } 056 057 public String getValue() { 058 return value; 059 } 060 061 public void setValue(String value) { 062 this.value = value; 063 } 064 065 public String getNotes() { 066 return notes; 067 } 068 069 public void setNotes(String notes) { 070 this.notes = notes; 071 } 072 073 public String getParaNotes() { 074 return paraNotes; 075 } 076 077 public void setParaNotes(String paraNotes) { 078 this.paraNotes = paraNotes; 079 } 080 081 public int getOrderNo() { 082 return orderNo; 083 } 084 085 public void setOrderNo(int orderNo) { 086 this.orderNo = orderNo; 087 } 088 089 public String getActionKey() { 090 return actionKey; 091 } 092 093 public void setActionKey(String actionKey) { 094 this.actionKey = actionKey; 095 } 096 097 public ContentType getContentType() { 098 return contentType; 099 } 100 101 public void setContentType(ContentType contentType) { 102 this.contentType = contentType; 103 } 104 105 public List<ApiParameter> getApiParameters() { 106 return apiParameters; 107 } 108 109 public void setApiParameters(List<ApiParameter> apiParameters) { 110 this.apiParameters = apiParameters; 111 } 112 113 public void addApiParameter(ApiParameter parameter) { 114 if (apiParameters == null) { 115 apiParameters = new LinkedList<>(); 116 } 117 apiParameters.add(parameter); 118 } 119 120 public boolean hasParameter() { 121 return apiParameters != null && apiParameters.size() > 0; 122 } 123 124 public ClassType getRetType() { 125 return retType; 126 } 127 128 public void setRetType(ClassType retType) { 129 this.retType = retType; 130 } 131 132 public Method getMethod() { 133 return method; 134 } 135 136 public void setMethod(Method method) { 137 this.method = method; 138 } 139 140 public Class<?> getControllerClass() { 141 return controllerClass; 142 } 143 144 public void setControllerClass(Class<?> controllerClass) { 145 this.controllerClass = controllerClass; 146 } 147 148 149 public void setMethodAndInfo(Method method, String controllerPath, HttpMethod[] defaultMethods, Class<?> containerClass) { 150 151 this.method = method; 152 this.actionKey = ApiDocUtil.getActionKey(method, controllerPath); 153 this.retType = ClassUtil.getClassType(method.getGenericReturnType(), getControllerClass()); 154 155 if (retType.isVoid() && containerClass != null) { 156 retType = new ClassType(containerClass); 157 } 158 159 this.retMockJson = ApiDocManager.me().buildMockJson(retType, method); 160 this.retRemarks = ApiDocManager.me().buildRemarks(retType, method); 161 162 setParameters(method, defaultMethods); 163 } 164 165 166 private void setParameters(Method method, HttpMethod[] defaultMethods) { 167 ApiParas apiParas = method.getAnnotation(ApiParas.class); 168 if (apiParas != null) { 169 for (ApiPara apiPara : apiParas.value()) { 170 addApiParameter(new ApiParameter(apiPara, defaultMethods)); 171 } 172 } 173 174 ApiPara apiPara = method.getAnnotation(ApiPara.class); 175 if (apiPara != null) { 176 addApiParameter(new ApiParameter(apiPara, defaultMethods)); 177 } 178 179 Parameter[] parameters = method.getParameters(); 180 Type[] paraTypes = method.getGenericParameterTypes(); 181 for (int i = 0; i < parameters.length; i++) { 182 183 ApiParameter apiParameter = new ApiParameter(); 184 Parameter parameter = parameters[i]; 185 apiParameter.setName(parameter.getName()); 186 apiParameter.setDataType(ClassUtil.getClassType(paraTypes[i], getControllerClass())); 187 188 if (parameter.getAnnotation(JsonBody.class) != null) { 189 apiParameter.setHttpMethods(new HttpMethod[]{HttpMethod.POST}); 190 } else { 191 apiParameter.setHttpMethods(defaultMethods); 192 } 193 194 ApiPara paraAnnotation = parameter.getAnnotation(ApiPara.class); 195 if (paraAnnotation != null) { 196 apiParameter.setValue(paraAnnotation.value()); 197 apiParameter.setNotes(paraAnnotation.notes()); 198 199 if (paraAnnotation.method().length > 0) { 200 apiParameter.setHttpMethods(paraAnnotation.method()); 201 } 202 203 if (paraAnnotation.require()) { 204 apiParameter.setNotBlank(true); 205 apiParameter.setRequire(true); 206 } 207 } 208 209 if (parameter.getAnnotation(NotNull.class) != null) { 210 apiParameter.setRequire(true); 211 } 212 213 if (parameter.getAnnotation(NotBlank.class) != null) { 214 apiParameter.setNotBlank(true); 215 apiParameter.setRequire(true); 216 } 217 218 if (parameter.getAnnotation(NotEmpty.class) != null) { 219 apiParameter.setNotEmpty(true); 220 apiParameter.setRequire(true); 221 } 222 223 if (parameter.getAnnotation(Email.class) != null) { 224 apiParameter.setEmail(true); 225 apiParameter.setRequire(true); 226 } 227 228 Min min = parameter.getAnnotation(Min.class); 229 if (min != null) { 230 apiParameter.setMin(min.value()); 231 apiParameter.setRequire(true); 232 } 233 234 Max max = parameter.getAnnotation(Max.class); 235 if (max != null) { 236 apiParameter.setMax(max.value()); 237 apiParameter.setRequire(true); 238 } 239 240 Pattern pattern = parameter.getAnnotation(Pattern.class); 241 if (pattern != null) { 242 apiParameter.setPattern(pattern.regexp()); 243 apiParameter.setRequire(true); 244 } 245 246 DefaultValue defaultValue = parameter.getAnnotation(DefaultValue.class); 247 if (defaultValue != null) { 248 apiParameter.setDefaultValue(defaultValue.value()); 249 } 250 251 addApiParameter(apiParameter); 252 } 253 } 254 255 public String getRetMockJson() { 256 return retMockJson; 257 } 258 259 public void setRetMockJson(String retMockJson) { 260 this.retMockJson = retMockJson; 261 } 262 263 public Map<String, List<ApiResponse>> getRetRemarks() { 264 return retRemarks; 265 } 266 267 public void setRetRemarks(Map<String, List<ApiResponse>> retRemarks) { 268 this.retRemarks = retRemarks; 269 } 270 271 @Override 272 public String toString() { 273 return "ApiOperation{" + 274 "value='" + value + '\'' + 275 ", notes='" + notes + '\'' + 276 ", actionKey='" + actionKey + '\'' + 277 '}'; 278 } 279}