Skip to content

Instantly share code, notes, and snippets.

@jcubic
Last active August 9, 2017 20:55
Show Gist options
  • Save jcubic/fe39ef13d5fef143d145c0d6c70e60bb to your computer and use it in GitHub Desktop.
Save jcubic/fe39ef13d5fef143d145c0d6c70e60bb to your computer and use it in GitHub Desktop.
ReflectService plugin
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="pl.jcubic.leash.service" version="1.0.0"
xmlns="http://apache.org/cordova/ns/plugins/1.0">
<name>Service</name>
<description>Apache Cordova Leash shell service plugin</description>
<license>Apache 2.0</license>
<keywords>cordova,exec,runtime,process,shell,command</keywords>
<js-module name="service" src="www/service.js">
<clobbers target="service"/>
</js-module>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="Service">
<param name="android-package" value="com.example.package.Service" />
<param name="onload" value="true" />
</feature>
</config-file>
<source-file src="src/com/example/package/Service.java"
target-dir="src/com/example/package/Service" />
<source-file src="src/com/example/package/ReflectService.java"
target-dir="src/com/example/package/Service" />
</platform>
</plugin>
package com.example.package;
import android.content.Context;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class ReflectService extends CordovaPlugin {
protected Method getMethod(String name) {
Class aClass = this.getClass();
Method[] methods = aClass.getMethods();
for (Method method : methods) {
if (method.getName().equals(name)) {
return method;
}
}
return null;
}
public String[] getMethods() {
Class aClass = this.getClass();
Method[] methods = aClass.getDeclaredMethods();
List<String> list = new ArrayList<String>();
int len = methods.length;
String[] result = new String[len];
for (Method method : methods) {
String name = method.getName();
if (Modifier.isPublic(method.getModifiers()) && !name.equals("initialize")) {
list.add(name);
}
}
return list.toArray(new String[list.size()]);
}
protected String[] jsonArrayToString(JSONArray args) {
String[] result = {};
try {
int len = args.length();
result = new String[len];
for (int i=0; i<len; ++i) {
result[i] = args.getString(i);
}
} catch (JSONException e) {}
return result;
}
protected String[] getStackTrace(Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
return sw.toString().split("\n");
}
@Override
public boolean execute(String action,
JSONArray args,
final CallbackContext callbackContext) throws JSONException {
if (!action.equals("execute")) {
final Method method = this.getMethod(action);
if (method == null) {
return false;
}
final Object[] arguments = this.jsonArrayToString(args);
cordova.getThreadPool().execute(new Runnable() {
public void run() {
JSONObject json;
Object result;
try {
result = method.invoke(ReflectService.this, arguments);
json = new JSONObject();
if (result instanceof Object[]) {
json.put("result", new JSONArray(result));
} else {
json.put("result", result);
}
json.put("error", null);
callbackContext.success(json);
} catch(JSONException e) {
callbackContext.success();
} catch(Exception e) {
try {
json = new JSONObject();
JSONObject error = new JSONObject();
error.put("error", "Exception");
error.put("code", 200);
error.put("message", e.getMessage());
String[] trace = ReflectService.this.getStackTrace(e);
error.put("trace", new JSONArray(trace));
json.put("error", error);
json.put("result", null);
callbackContext.success(json);
} catch(JSONException ee) {
callbackContext.success();
}
}
}
});
return true;
}
return false;
}
}
package com.example.package;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
public class Service extends ReflectService {
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
// your init code here
}
public String echo(String input) {
if (input.equals("ping")) {
return "pong";
} else {
return null;
}
}
}
window.Service = function Service(callback) {
function call(method, args, callback) {
return cordova.exec(function(response) {
callback(null, response);
}, function(error) {
callback(error);
}, "Service", method, args || []);
}
var service = {};
call("getMethods", [], function(err, response) {
if (response.result instanceof Array) {
response.result.forEach(function(method) {
service[method] = function() {
var args = [].slice.call(arguments);
return function(callback) {
return call(method, args, function(err, response) {
err = err || response.error;
if (err) {
callback(err);
} else {
callback(null, response.result);
}
});
};
};
});
callback(service);
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment