cn.mapway.document.helper.GwtConnextorExport Maven / Gradle / Ivy
Show all versions of api-tools-doc Show documentation
package cn.mapway.document.helper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.mapway.document.module.ApiDoc;
import cn.mapway.document.module.Group;
import org.nutz.lang.Strings;
import cn.mapway.document.module.Entry;
import cn.mapway.document.module.ObjectInfo;
import cn.mapway.document.resource.Template;
/**
* 输出Java Connect 代码.
*
* @author zhangjianshe
*/
public class GwtConnextorExport {
/**
* The modules.
*/
Map modules;
/**
* Instantiates a new gwt connextor export.
*/
public GwtConnextorExport() {
modules = new HashMap();
}
/**
* 输出API 对应的 Java Connector 模型在独立的文件中
*
* @param api the api
* @param packageName the package name
* @param className the class name
* @return list
*/
public List export2(ApiDoc api, String packageName, String className) {
entries = new HashMap();
ArrayList clazzs = new ArrayList();
StringBuilder imports = new StringBuilder();
imports.append("import " + packageName + ".module.*;\r\n");
StringBuilder sb = new StringBuilder();
modules = new HashMap();
Group root = api.root;
recurse(sb, root, modules);
String template;
template = Scans.readResource("cn.mapway.document.resource", "gwtconnect.txt");
processModuleMody(packageName, modules, clazzs);
Map map = new HashMap();
map.put("package", packageName);
map.put("name", className);
map.put("basepath", "");
map.put("importModules", imports.toString());
map.put("apis", sb.toString());
map.put("modules", "");
JavaClassContent jcc = new JavaClassContent();
jcc.body = replace(template, map);
jcc.className = className;
jcc.packageName = packageName;
clazzs.add(jcc);
return clazzs;
}
private void processModuleMody(String packageName, Map ms,
ArrayList clazzs) {
for (String key : ms.keySet()) {
ObjectInfo oi = ms.get(key);
StringBuilder sb = new StringBuilder();
sb.append("package " + packageName + ".module;\r\n\r\n");
sb.append("import com.google.gwt.core.client.*;\r\n");
sb.append("\r\n/**\r\n");
sb.append(" (" + oi.title + ").\r\n");
sb.append(" " + oi.summary + "\r\n");
sb.append(" */\r\n");
sb.append("public class " + getType(unwrapType(oi.type)) + " extends JavaScriptObject {\r\n");
sb.append(" protected " + getType(unwrapType(oi.type)) + "(){}\r\n");
sb.append(" public final static native " + getType(unwrapType(oi.type))
+ " create()/*-{\r\n return {};\r\n }-*/;\r\n");
for (ObjectInfo fi : oi.fields) {
sb.append(" /**\r\n * 获取" + fi.title + " " + fi.summary + ".\r\n */\r\n");
sb.append(" public final native " + getType(fi.type) + " get"
+ Strings.upperFirst(fi.name) + "() /*-{\r\n" + " return this." + fi.name
+ ";\r\n }-*/;\r\n");
sb.append(" /**\r\n " + fi.title + "\r\n " + fi.summary + "\r\n */\r\n");
sb.append(" public final native void set" + Strings.upperFirst(fi.name) + "("
+ getType(fi.type) + " v) /*-{\r\n" + " this." + fi.name
+ " = v;\r\n }-*/;\r\n");
}
sb.append(" /**\r\n" + " * 对象字符串\r\n" + " */\r\n"
+ " public final String toJson() {\r\n" + " return JsonUtils.stringify(this);\r\n"
+ " }");
sb.append("}\r\n");
JavaClassContent jcc = new JavaClassContent();
jcc.body = sb.toString();
jcc.className = getType(unwrapType(oi.type));
jcc.packageName = packageName + ".module";
clazzs.add(jcc);
}
}
/**
* 输出API 对应的 Java Connector
*
* public resp doSomthing(Req req) {
*
* }.
*
* @param api the api
* @param packageName the package name
* @param className the class name
* @return the string
*/
public String export(ApiDoc api, String packageName, String className) {
entries = new HashMap();
StringBuilder imports = new StringBuilder();
StringBuilder sb = new StringBuilder();
StringBuilder modulesBody = new StringBuilder();
modules = new HashMap();
Group root = api.root;
recurse(sb, root, modules);
String template;
try {
template = Template.readTemplate("/main/java/mapway/document/resource/gwtconnect.txt");
} catch (IOException e) {
e.printStackTrace();
return "";
}
processModuleMody(modules, modulesBody);
Map map = new HashMap();
map.put("package", packageName);
map.put("name", className);
map.put("basepath", "");
map.put("importModules", imports.toString());
map.put("apis", sb.toString());
map.put("modules", modulesBody.toString());
return replace(template, map);
}
/**
* Replace.
*
* @param str the str
* @param data the data
* @return the string
*/
public String replace(String str, Map data) {
try {
return StrUtil.composeMessage(str, data);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* Process module mody.
*
* @param ms the ms
* @param modulesBody the modules body
*/
private void processModuleMody(Map ms, StringBuilder modulesBody) {
for (String key : ms.keySet()) {
ObjectInfo oi = ms.get(key);
modulesBody.append("\r\n/**");
modulesBody.append(" " + oi.title + "\r\n");
modulesBody.append(" " + oi.summary);
modulesBody.append("*/\r\n");
modulesBody.append("public static class " + getType(unwrapType(oi.type))
+ " extends JavaScriptObject{\r\n");
modulesBody.append("protected " + getType(unwrapType(oi.type)) + "(){}\r\n");
modulesBody.append("public final static native " + getType(unwrapType(oi.type))
+ " create()/*-{return {}}-*/;\r\n");
for (ObjectInfo fi : oi.fields) {
modulesBody.append("/**\r\n 获取" + fi.title + "\r\n " + fi.summary + "\r\n */\r\n");
modulesBody.append(" public final native " + getType(fi.type) + " " + fi.name
+ "() /*-{\r\n" + "return this." + fi.name + ";}-*/;\r\n");
modulesBody.append("/**\r\n " + fi.title + "\r\n " + fi.summary + "\r\n */\r\n");
modulesBody.append(" public final native void " + fi.name + "(" + getType(fi.type)
+ " v) /*-{\r\n" + "this." + fi.name + "=v;}-*/;\r\n");
}
modulesBody.append("}\r\n");
}
}
/**
* Gets the type.
*
* @param type the type
* @return the type
*/
private String getType(String type) {
if (type.startsWith("List")) {
String subtype = type.substring(5, type.length() - 1);
if (subtype.equals("java.lang.String")) {
return "JsArrayString";
} else if (subtype.equals("java.lang.Boolean") || subtype.equals("bool")) {
return "JsArrayBoolean";
} else if (subtype.equals("int") || subtype.equals("java.lang.Integer")
|| subtype.equals("java.lang.Long") || subtype.equals("long")
|| subtype.equals("java.lang.Byte") || subtype.equals("byte")
|| subtype.equals("java.lang.Short") || subtype.equals("short")) {
return "JsArrayInteger";
} else if (subtype.equals("double") || subtype.equals("java.lang.Double")
|| subtype.equals("float") || subtype.equals("java.lang.Float")) {
return "JsArrayNumber";
}
if (subtype.equals("java.util.Map")) {
return "JsArray";
}
return "JsArray<" + getType(subtype) + ">";
}
String t = type;
int index = type.lastIndexOf(".");
if (index > 0) {
return type.substring(index + 1);
}
return changeTypeFromObject2Native(t);
}
/**
* 将 Java对象类型转化为原生类型 "int", "Integer", "float", "Float", "Double", "double", "long", "Long",
* "Date", "DateTime", "String", "boolean", "Boolean", "char", "short", "byte", "Timestamp", "Map"
*
* @param type
* @return
*/
private String changeTypeFromObject2Native(String type) {
if ("Integer".equals(type)) {
return "int";
}
if ("Double".equals(type)) {
return "double";
}
if ("Boolean".equals(type)) {
return "boolean";
}
if ("Char".equals(type)) {
return "char";
}
if ("Short".equals(type)) {
return "int";
}
if ("Long".equals(type)) {
return "int";
}
if ("long".equals(type)) {
return "int";
}
if ("Float".equals(type)) {
return "double";
}
if ("float".equals(type)) {
return "double";
}
return type;
}
/**
* 循环处理接口.
*
* @param sb the sb
* @param root the root
* @param modules2 the modules 2
*/
private void recurse(StringBuilder sb, Group root, Map modules2) {
for (Entry e : root.entries) {
processEntry(e, sb, modules2);
}
for (Group g : root.subGroups) {
recurse(sb, g, modules2);
}
}
/**
* Process entry.
*
* @param e the e
* @param sb the sb
* @param modules2 the modules 2
*/
private void processEntry(Entry e, StringBuilder sb, Map modules2) {
for (ObjectInfo info : e.input) {
processModule(info, modules2);
}
processModule(e.output, modules2);
processEntryBodyAsync(e, sb);
}
/**
* The Entries.
*/
HashMap entries = new HashMap();
/**
* Process entry body async.
*
* @param e the e
* @param sb the sb
*/
private void processEntryBodyAsync(Entry e, StringBuilder sb) {
if (e.input.size() == 0) {
// TODO 处理无参数的情况
return;
}
int count = 0;
if (entries.containsKey(e.methodName)) {
count = entries.get(e.methodName);
count++;
entries.put(e.methodName, count);
} else {
count = 0;
entries.put(e.methodName, 0);
}
sb.append("/**\r\n");
sb.append(" *" + e.title + "\r\n");
sb.append(" *" + Strings.sBlank(e.summary) + "\r\n");
sb.append("*/" + "\r\n");
sb.append("public void " + (e.methodName + (count == 0 ? "" : ("" + count))) + "(final "
+ getType(unwrapType(e.input.get(0).type)) + " req ,final ICallback<"
+ getType(unwrapType(e.output.type)) + "> handler) throws Exception{\r\n");
sb.append("\tif (handler == null) {\r\n");
sb.append("\treturn;\r\n}\r\n");
String type = getType(unwrapType(e.output.type));
// TODO 解析更多 invoke method
String invokeMethod = e.invokeMethods.get(0);
if (invokeMethod.compareToIgnoreCase("post") == 0) {
if (type.equals("String")) {
sb.append("doPostString(\"" + e.relativePath + "\", JsonUtils.stringify(req), handler);");
} else {
sb.append(" doPost(\"" + e.relativePath + "\", JsonUtils.stringify(req), handler);");
}
} else {
if (type.equals("String")) {
sb.append(" doGetString(\"" + e.relativePath + "\", JsonUtils.stringify(req), handler);");
} else {
sb.append(" doGet(\"" + e.relativePath + "\", JsonUtils.stringify(req), handler);");
}
}
sb.append("\t\r\n");
sb.append("}\r\n");
}
/**
* List> ===> ?.
*
* @param t the t
* @return the string
*/
String unwrapType(String t) {
if (t.startsWith("List")) {
return t.substring(5, t.length() - 1);
}
return t;
}
/**
* Process module.
*
* @param info the info
* @param modules2 the modules 2
*/
private void processModule(ObjectInfo info, Map modules2) {
String t = unwrapType(info.type);
if (isPrimitive(t)) {
return;
}
if (!modules2.containsKey(t)) {
// 检查参数类型是否有重名的
checkDoubleName(modules2, info);
modules2.put(t, info);
}
for (ObjectInfo oi : info.fields) {
processModule(oi, modules2);
}
}
/**
* Check double name.
*
* @param modules2 the modules 2
* @param info the info
*/
private void checkDoubleName(Map modules2, ObjectInfo info) {
String t = getType(unwrapType(info.type));
for (String key : modules2.keySet()) {
String t1 = getType(unwrapType(key));
if (t.equals(t1)) {
// 有重名
info.type = info.type.replaceAll("\\.", "");
break;
}
}
}
/**
* The ps.
*/
private static String[] ps = {"int", "Integer", "float", "Float", "Double", "double", "long",
"Long", "Date", "DateTime", "String", "boolean", "Boolean", "char", "short", "byte",
"Timestamp", "Map"};
/**
* Checks if is primitive.
*
* @param type the type
* @return true, if is primitive
*/
private boolean isPrimitive(String type) {
for (String s : ps) {
if (type.contains(s)) {
return true;
}
}
return false;
}
}