package reptile.apidoc;
import entity.RequestInfo;
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.StringUtils;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WikiApiDocMain {
public static void main(String[] args) {
String path = "temp" + File.separator + "apidoc" + File.separator
+ "wikiapi.txt";
ArrayList<RequestInfo> infos = parseApiDoc(path);
genRetrofitCode(infos);
}
public static ArrayList<RequestInfo> parseApiDoc(String path) {
File file = new File(path);
String response = FileUtils.readToString(file, "UTF-8");
Document parse = Jsoup.parse(response);
ArrayList<RequestInfo> requestInfos = new ArrayList<>();
Elements names = parse.getElementsByTag("h2");
ArrayList<String> titleList = new ArrayList<>();
for(Element nameElement : names) {
String title = nameElement.text();
Pattern pattern = Pattern.compile("[\\d]{1,2}");
Matcher matcher = pattern.matcher(title);
if(matcher.find(0)) {
titleList.add(title);
}
}
Elements rootElements = parse.getElementsByTag("table");
for (Element rootElement : rootElements) {
if (!rootElement.attr("class").contains("confluenceTable")) {
continue;
}
if (rootElement.child(0).childNodeSize() < 2) {
continue;
}
Elements tds = rootElement.getElementsByTag("td");
if (tds.size() == 0) {
continue;
}
RequestInfo requestInfo = new RequestInfo();
// url
Element urlElement = tds.get(0);
String url = urlElement.text();
List<String> paramsFromUrl = new ArrayList<>();
// get类型url可能包含?
if(url.contains("?")) {
int getIndex = url.indexOf("?");
for (String s : url.substring(getIndex+1).split("&")) {
paramsFromUrl.add(s.split("=")[0]);
}
url = url.substring(0, getIndex);
}
requestInfo.setUrl(url);
// name
requestInfo.setName("");
// method
String method = tds.get(1).text();
requestInfo.setMethod(method);
// params
ArrayList<RequestParam> params = new ArrayList<>();
Elements paramsElements = tds.get(2).getElementsByTag("tr");
for (int i = 1; i < paramsElements.size(); i++) {
Element paramElement = paramsElements.get(i);
String name = paramElement.child(0).text();
String type = "String";
String desc = paramElement.child(1).text();
String restType;
if(url.contains("{" + name + "}")) {
restType = "Path";
} else if(method.equalsIgnoreCase("get")) {
restType = "Query";
} else {
restType = "Body";
}
RequestParam param = new RequestParam(name, type, desc, null);
param.setRestType(restType);
params.add(param);
// 如果请求参数表中,已经有参数,则先删除。没有的话在后面补上
if(paramsFromUrl.contains(name)) {
paramsFromUrl.remove(name);
}
}
for(String param : paramsFromUrl) {
// 只从url获取到的信息有限,类型写死为String
params.add(new RequestParam(param, "String", "", null));
}
requestInfo.setParams(params);
boolean has = false;
for(RequestInfo ri : requestInfos) {
if(ri.getUrl().equals(requestInfo.getUrl()) && ri.getMethod().equals(requestInfo.getMethod())) {
has = true;
break;
}
}
if(!has) {
requestInfos.add(requestInfo);
}
}
for (int i = 0; i < requestInfos.size(); i++) {
if(i < titleList.size()) {
requestInfos.get(i).setName(titleList.get(i));
}
}
return requestInfos;
}
private static void genRetrofitCode(ArrayList<RequestInfo> infos) {
String baseUrl = "http://dev-api.qbaolive.com/v1/";
for (RequestInfo info : infos) {
StringBuilder sb = new StringBuilder();
// 方式注释里参数
StringBuilder sbAnnotation = new StringBuilder();
ArrayList<RequestParam> params = info.getParams();
if (params != null && params.size() > 0) {
sbAnnotation.append(StringUtils.formatSingleLine(1, " *"));
ArrayList<RequestParam> bodyParams = new ArrayList<>();
for(RequestParam param : info.getParams()) {
if(param.getRestType().equals("Body")) {
bodyParams.add(param);
} else {
// 方式注释里参数
// * @param name 姓名
sbAnnotation.append(StringUtils.formatSingleLine(
1, " * @param " + param.getName() + " " + param.getDes()));
}
}
if(bodyParams.size() > 0) {
StringBuilder sbBodyParams = new StringBuilder();
for (int i = 0; i < bodyParams.size(); i++) {
RequestParam param = bodyParams.get(i);
if(i == 0) {
sbAnnotation.append(StringUtils.formatSingleLine(
1, " * @param body " + param.getName() + " " + param.getDes()));
} else {
sbAnnotation.append(StringUtils.formatSingleLine(
1, " * " + param.getName() + " " + param.getDes()));
}
sbBodyParams.append(",").append(param.getName());
}
}
}
sb.append(StringUtils.formatSingleLine(1, "/**"));
sb.append(StringUtils.formatSingleLine(1, " * " + info.getName()));
if(sbAnnotation.length() > 0) {
sb.append(sbAnnotation.toString());
}
sb.append(StringUtils.formatSingleLine(1, " */"));
String url = info.getUrl();
String str1 = String.format("@%s(\"%s\")",
info.getMethod(),
url.replaceFirst(baseUrl, ""));
sb.append(StringUtils.formatSingleLine(1, str1));
url = url.replaceAll("/\\{[a-zA-Z0-9]+\\}", "");
String methodName = url.substring(url.lastIndexOf("/") + 1);
String str2 = String.format("Observable<HttpResult<String>> %s(", methodName);
sb.append(StringUtils.formatSingleLine(1, str2));
if(info.getParams().size() > 0) {
ArrayList<RequestParam> bodyParams = new ArrayList<>();
for(RequestParam param : info.getParams()) {
if(param.getRestType().equals("Body")) {
bodyParams.add(param);
} else {
String p = String.format("@%s(\"%s\") String %s,", param.getRestType(), param.getName(), param.getName());
sb.append(StringUtils.formatSingleLine(3, p));
}
}
if(bodyParams.size() > 0) {
sb.append(StringUtils.formatSingleLine(3, "@Body Object body);"));
} else {
sb.replace(sb.lastIndexOf(","), sb.length(), ");");
}
} else {
sb.replace(sb.length()-1, sb.length(), ");");
}
sb.append("\n");
System.out.println(sb.toString());
}
}
private static void genCode(ArrayList<RequestInfo> infos) {
StringBuilder sb = new StringBuilder();
for (RequestInfo info : infos) {
String urlName = info.getName();
String url = info.getUrl();
// 方式注释里参数
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) {
// 方式注释里参数
// * @param name 姓名
sbAnotation.append(StringUtils.formatSingleLine(
1,
" * @param " + param.getName() + " "
+ param.getDes()));
// 方法参数里参数 String phone, HttpListener<Object> listener
sbParam.append(param.getType() + " " + param.getName()
+ ", ");
// 方法内容里参数 params.put("phone", phone);
sbBody.append(StringUtils.formatSingleLine(
2,
"params.put(\"" + param.getName() + "\", "
+ param.getName() + ");"));
}
sbAnotation.append("\n");
}
sb.append(StringUtils.formatSingleLine(1, "/**"));
sb.append(StringUtils.formatSingleLine(1, " * " + info.getDes()));
sb.append(sbAnotation.toString());
sb.append(StringUtils.formatSingleLine(1, " */"));
// 方法名
String methodName = "request";
String[] nameItems = url.split("/");
for (int i = nameItems.length - 1; i > 0; i--) {
if (nameItems[i].contains("{")) {
continue;
}
methodName = nameItems[i];
break;
}
sb.append(StringUtils.formatSingleLine(1, "public static void "
+ methodName + "("
+ sbParam.toString() + ") {"));
// url
sb.append(StringUtils.formatSingleLine(2, "String url = \"" + info.getUrl() + "\";"));
String method = "Request.Method." + info.getMethod();
// 参数,如果是post放到map里,如果是get则拼接到url里
if (info.getMethod().equals("post")) {
sb.append(StringUtils.formatSingleLine(2,
"HashMap<String, Object> params = new HashMap<String, Object>();"));
sb.append(sbBody.toString());
sb.append(StringUtils.formatSingleLine(2,
"executeRequest(" + method + ", url, params, Object.class, listener, errorListener);"));
} else {
for (RequestParam param : info.getParams()) {
sb.append(StringUtils.formatSingleLine(2,
"url = url.replace(\"{" + param.getName() + "}\", String.valueOf(" + param.getName() + "));"));
}
sb.append(StringUtils.formatSingleLine(2,
"executeRequest(" + method + ", url, null, Object.class, listener, errorListener);"));
}
sb.append(StringUtils.formatSingleLine(1, "}"));
sb.append("\n");
}
System.out.println(sb.toString());
}
}