
com.flipboard.goldengate.BridgeMethod Maven / Gradle / Ivy
package com.flipboard.goldengate;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.VariableElement;
public class BridgeMethod {
public final String javaName;
public final String name;
public final List parameters = new ArrayList<>();
public BridgeCallback callback;
public BridgeMethod(ExecutableElement e) {
this.javaName = e.getSimpleName().toString();
this.name = e.getAnnotation(Method.class) != null ? e.getAnnotation(Method.class).value() : javaName;
for (int i = 0; i < e.getParameters().size(); i++) {
VariableElement param = e.getParameters().get(i);
boolean isJavascriptCallback = param.getAnnotation(JavascriptCallback.class) != null;
if (i == e.getParameters().size() - 1 && Util.isCallback(param) && !isJavascriptCallback) {
callback = new BridgeCallback(param);
} else {
if (isJavascriptCallback) {
if (Util.isCallback(param)) {
parameters.add(new BridgeCallback(param));
} else {
throw new IllegalArgumentException("Param with annotation @JavascriptCallback must be of type com.flipboard.goldengate.Callback");
}
} else {
parameters.add(new BridgeParameter(param));
}
}
}
}
public MethodSpec toMethodSpec(BridgeInterface bridge) {
MethodSpec.Builder methodSpec = MethodSpec.methodBuilder(javaName).addModifiers(Modifier.PUBLIC);
for (int i = 0; i < parameters.size(); i++) {
methodSpec.addParameter(TypeName.get(parameters.get(i).type), parameters.get(i).name, Modifier.FINAL);
}
if (callback != null) {
methodSpec.addParameter(TypeName.get(callback.type), callback.name, Modifier.FINAL);
methodSpec.addCode(CodeBlock.builder()
.addStatement("$T id = receiverIds.incrementAndGet()", long.class)
.add("this.resultBridge.registerCallback(id, new Callback<$T>() {\n", String.class)
.indent()
.add("@$T\n", Override.class)
.add("public void onResult(String result) {\n")
.indent()
.addStatement("$N.onResult(fromJson(result, $T.class))", callback.name, callback.genericType)
.unindent()
.add("}\n")
.unindent()
.addStatement("})")
.build());
}
methodSpec.addStatement("$T<$T, $T> idMap = new $T<>()", Map.class, String.class, Long.class, HashMap.class);
for (BridgeParameter parameter : parameters) {
if (parameter instanceof BridgeCallback) {
BridgeCallback callbackParameter = (BridgeCallback) parameter;
methodSpec.addCode(CodeBlock.builder()
.addStatement("idMap.put($S, receiverIds.incrementAndGet())", callbackParameter.name)
.add("this.resultBridge.registerCallback(idMap.get($S), new Callback<$T>() {\n", callbackParameter.name, String.class)
.indent()
.add("@$T\n", Override.class)
.add("public void onResult(String result) {\n")
.indent()
.addStatement("$N.onResult(fromJson(result, $T.class))", callbackParameter.name, callbackParameter.genericType)
.unindent()
.add("}\n")
.unindent()
.addStatement("})")
.build());
}
}
if (parameters.size() > 0) {
String parameterList = "";
for (int i = 0; i < parameters.size(); i++) {
BridgeParameter parameter = parameters.get(i);
if (parameter instanceof BridgeCallback) {
BridgeCallback callbackParameter = (BridgeCallback) parameter;
parameterList += "\"GoldenGate$$CreateCallback(\"+idMap.get(\"" + callbackParameter.name + "\")+\")\"";
} else if (i < parameters.size()) {
parameterList += "toJson(" + parameter.name + ")";
}
if (i < parameters.size()-1) {
parameterList += " + \", \" + ";
}
}
if (callback == null) {
CodeBlock.Builder codeBlock = CodeBlock.builder();
codeBlock.addStatement("$T javascript = \"$L(\"+$L+\");\"", String.class, name, parameterList);
if (bridge.isDebug) {
codeBlock.addStatement("android.util.Log.d($S, javascript)", bridge.name);
}
codeBlock.addStatement("this.webView.loadUrl(\"javascript:\" + javascript)");
methodSpec.addCode(codeBlock.build());
} else {
CodeBlock.Builder codeBlock = CodeBlock.builder();
codeBlock.addStatement("$T javascript = \"$L.onResult(JSON.stringify({receiver:\"+id+\", result:JSON.stringify($L(\"+$L+\"))}));\"", String.class, bridge.name, name, parameterList);
if (bridge.isDebug) {
codeBlock.addStatement("android.util.Log.d($S, javascript)", bridge.name);
}
codeBlock.addStatement("this.webView.loadUrl(\"javascript:\" + javascript)");
methodSpec.addCode(codeBlock.build());
}
} else {
if (callback == null) {
CodeBlock.Builder codeBlock = CodeBlock.builder();
codeBlock.addStatement("$T javascript = \"$L();\"", String.class, name);
if (bridge.isDebug) {
codeBlock.addStatement("android.util.Log.d($S, javascript)", bridge.name);
}
codeBlock.addStatement("this.webView.loadUrl(\"javascript:\" + javascript)");
methodSpec.addCode(codeBlock.build());
} else {
CodeBlock.Builder codeBlock = CodeBlock.builder();
codeBlock.addStatement("$T javascript = \"$L.onResult(JSON.stringify({receiver:\"+id+\", result:JSON.stringify($L())}));\"", String.class, bridge.name, name);
if (bridge.isDebug) {
codeBlock.addStatement("android.util.Log.d($S, javascript)", bridge.name);
}
codeBlock.addStatement("this.webView.loadUrl(\"javascript:\" + javascript)");
methodSpec.addCode(codeBlock.build());
}
}
return methodSpec.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy