package reptile.swagger; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import entity.RequestParam; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import utils.FileUtils; import utils.JsonUtils; import utils.StringUtils; import entity.Json2JavaElement; import entity.RequestInfo; public class SwaggerDocGenerator { public static void main(String[] args) { ArrayList<RequestInfo> infos = parseDocFromHtml("temp" + File.separator + "apidoc" + File.separator + "swagger.txt"); System.out.println("接口总数量:" + infos.size()); System.out.println(infos); genCode(infos); } public static void genCode(ArrayList<RequestInfo> infos) { StringBuilder sbUrl = new StringBuilder(); StringBuilder sb = new StringBuilder(); for(RequestInfo info : infos) { // /** // * 查询指定服务申请详细信息 // */ // public static final String SERVICEAPPLIES = "/rest/serviceApplies/{applyId}"; String name = info.getName(); String url = info.getUrl(); String urlName = /*info.getMethod() + "_" + */url .replace("/rest/", "") .replace("/", "_") .replace("{", "") .replace("}", ""); String responseBeanName = "Object"; if(info.getResponseJson() != null) { // user/test -> UserTestResponse String[] split = url.split("/"); responseBeanName = StringUtils.firstToUpperCase(split[0]) + StringUtils.firstToUpperCase(split[1]) + "Response"; String jsonJava = info.getResponseJson(); // TODO 特殊处理,继承基类 extends BaseEntity jsonJava = jsonJava.replace("JsonBeans", responseBeanName + " extends BaseEntity"); File file = new File("temp" + File.separator + "entity" + File.separator + responseBeanName + ".java"); FileUtils.writeString2File(jsonJava, file, "utf-8"); } // 作为url末尾直接拼装的参数,一般只有一个 String endParam = null; String endParamName = null; Pattern pattern = Pattern.compile("\\{[\\s\\S]+\\}"); Matcher matcher = pattern.matcher(url); if(matcher.find()) { endParam = matcher.group(); endParamName = endParam.replace("{", "").replace("}", ""); url = url.replace(endParam, ""); } sbUrl.append(StringUtils.formatSingleLine(1, "/**")); sbUrl.append(StringUtils.formatSingleLine(1, " * " + name)); sbUrl.append(StringUtils.formatSingleLine(1, " */")); sbUrl.append(StringUtils.formatSingleLine(1, "public static final String " + urlName.toUpperCase() + " = \"" + url + "\";" + (endParam == null ? "" : "// " + endParam))); sbUrl.append("\n"); // /** // * 注册用户 // * // * @param phone 手机号 (可选项: 1; 2) // * @param listener // */ // public static void userSignUp(String phone, HttpListener<User> listener) { // String time = String.valueOf(getCurrentTime()); // Map<String, Object> params = new HashMap<String, Object>(); // params.put("phone", phone); // params.put("time", time); // doHttp(Urls.getUrl(Urls.USER_SIGN_UP), "get", params, User.class, listener); // } // endParam模式的为 // String time = String.valueOf(getCurrentTime()); // doHttp(Urls.getUrl(Urls.USER_SIGN_UP) + phone, params, User.class, listener); // 方式注释里参数 StringBuilder sbAnotation = new StringBuilder(); // 方法参数里参数 StringBuilder sbParam = new StringBuilder(); // 方法内容里参数 StringBuilder sbBody = new StringBuilder(); ArrayList<RequestParam> params = info.getParams(); if(params != null && params.size() > 0) { sbAnotation.append(StringUtils.formatSingleLine(1, " *")); for(RequestParam param : params) { // 方式注释里参数 sbAnotation.append("\t * @param") .append(" ").append(param.getName()) .append(" ").append(param.getDes()); ArrayList<String> options = param.getSelectOptions(); if(options != null && options.size() > 0) { sbAnotation.append(" (可选项: "); for(int i=0; i<options.size(); i++) { if(i > 0) { sbAnotation.append("; "); } sbAnotation.append(options.get(i)); } sbAnotation.append(")"); } sbAnotation.append("\n"); // 方法参数里参数 String phone, HttpListener<User> listener sbParam.append(param.getType() + " " + param.getName() + ", "); // 方法内容里参数 params.put("phone", phone); sbBody.append(StringUtils.formatSingleLine(2, "params.put(\"" + param.getName() + "\", " + param.getName() + ");")); } } sbParam.append("HttpListener<" + responseBeanName + "> listener"); sb.append(StringUtils.formatSingleLine(1, "/**")); sb.append(StringUtils.formatSingleLine(1, " * " + name)); if(endParamName != null) { sb.append(StringUtils.formatSingleLine(1, " *")) .append("\t * @param").append(" ").append(endParamName); } else { sb.append(sbAnotation.toString()); } sb.append(StringUtils.formatSingleLine(1, " */")); StringBuilder methodNameSb = new StringBuilder(); String[] nameItems = urlName.split("_"); for(int i=0; i<nameItems.length; i++) { String nameItem = nameItems[i]; if(i>0) { nameItem = nameItem.substring(0, 1).toUpperCase() + nameItem.substring(1); } methodNameSb.append(nameItem); } sb.append(StringUtils.formatSingleLine(1, "public static void " + methodNameSb.toString() + "(" + (endParamName==null?"":"String "+endParamName+", ") + sbParam.toString() + ") {")); sb.append(StringUtils.formatSingleLine(2, "HashMap<String, Object> params = new HashMap<String, Object>();")); sb.append(sbBody.toString()); sb.append(StringUtils.formatSingleLine(2, "doHttp(URLs.getUrl(URLs." + urlName.toUpperCase() + ")" + (endParamName==null?"":" + "+endParamName) + ", \"" + info.getMethod() + "\", params, " + responseBeanName + ".class, listener);")); sb.append(StringUtils.formatSingleLine(1, "}")); sb.append("\n"); } System.out.println(sbUrl.toString()); System.out.println(sb.toString()); } public static ArrayList<RequestInfo> parseDocFromHtml(String path) { ArrayList<RequestInfo> requestInfos = new ArrayList<RequestInfo>(); File file = new File(path); String response = FileUtils.readToString(file, "UTF-8"); Document parse = Jsoup.parse(response); // 总接口类型 // <li id="resource_用户相关api" class="resource"> Elements typeElements = parse.getElementsByClass("resource"); for(Element typeElement : typeElements) { // id为 "resource_用户相关api" String apiTitle = typeElement.id().split("_")[1]; // 获取该类型下具体接口 // <ul class="operations"> Elements apiElements = typeElement.getElementsByClass("operations"); // System.out.println(apiTitle + " ... " + apiElements.size()); for(Element apiElement : apiElements) { RequestInfo requestInfo = new RequestInfo(); // header Element headingElement = apiElement.getElementsByClass("heading").get(0); // 接口名称 // <ul class="options"> String name = headingElement.getElementsByClass("options").get(0).text(); requestInfo.setName(name); // 接口方式 // <ul class="http_method"> String method = headingElement.getElementsByClass("http_method").get(0).text(); requestInfo.setMethod(method); // 接口地址 // <ul class="path"> String url = headingElement.getElementsByClass("path").get(0).text(); requestInfo.setUrl(url); // content Element contentElement = apiElement.getElementsByClass("content").get(0); // 提交参数 // <tbody class="operation-params"> Elements paramsElements = contentElement.getElementsByClass("operation-params"); if(paramsElements != null && paramsElements.size() > 0) { // 有参数才做处理 Element paramsElement = paramsElements.get(0); // 一行对应一个参数 // <tr> Elements paramElements = paramsElement.children(); ArrayList<RequestParam> params = new ArrayList<RequestParam>(); for(Element paramElement : paramElements) { // 一列对应参数的一个属性,共5列,分别为 名称,值,描述,参数类型,数据类型 // <td> Elements columeElement = paramElement.children(); String paramName = columeElement.get(0).text(); String paramDes = columeElement.get(2).text(); String pType = columeElement.get(3).text(); if(pType.equals("query")) { // 如果参数类型为query,则为数据类型为基础类型 String paramType = columeElement.get(4).text(); // 数据值可能为可选项 Elements valueOptionsElements = columeElement.get(1).getElementsByTag("option"); ArrayList<String> valueOptions = new ArrayList<String>(); for(Element valueOptionsElement : valueOptionsElements) { String option = valueOptionsElement.text(); if(option != null && !option.trim().equals("")) { valueOptions.add(option); } } params.add(new RequestParam(paramName, paramType, paramDes, valueOptions)); requestInfo.setParams(params); } else if(pType.equals("body")) { // 如果参数类型为body,则为数据类型为json字符串,且一般只有一行 Element jsonElement = columeElement.get(4); // 解析json中的多个参数 requestInfo.setParams(parseJsonParams(jsonElement)); break; } } } requestInfos.add(requestInfo); // System.out.println(requestInfo.toString()); } } return requestInfos; } private static ArrayList<RequestParam> parseJsonParams(Element jsonElement) { ArrayList<RequestParam> requestParams = new ArrayList<RequestParam>(); String jsonStr = jsonElement.getElementsByClass("json").text(); if(!jsonStr.isEmpty()) { List<Json2JavaElement> jsonBeanTree = JsonUtils.getJsonBeanTree(jsonStr); for(Json2JavaElement j2je : jsonBeanTree) { String paramName = j2je.getName(); String paramDes = ""; // 此类格式post参数没有描述 Class<?> type = j2je.getType(); String pType = type == null ? "String" : j2je.getType().getSimpleName(); requestParams.add(new RequestParam(paramName, pType, paramDes, new ArrayList<String>())); } } return requestParams; } }