Skip to content

Commit

Permalink
Android Invocation: Exchange com.fasterxml.jackson with org.json pars…
Browse files Browse the repository at this point in the history
…er (#415)

* exchange fasterxml.jackson with org.json implementation

This allows us to eliminate this often painful dependency

Closes #351

* removed org.json from runtime dependencies

* add gradlew test to CI
  • Loading branch information
DanielMSchmidt authored and rotemmiz committed Nov 22, 2017
1 parent 011b18c commit fc6a1a2
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 75 deletions.
3 changes: 1 addition & 2 deletions detox/android/detox/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,12 @@ dependencies {
})

compile 'org.apache.commons:commons-lang3:3.4'
compile 'com.fasterxml.jackson.core:jackson-core:2.2.3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.2.3'

compile 'com.android.support.test:runner:1.0'
compile 'com.android.support.test:rules:1.0'
compile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'

testCompile 'org.json:json:20140107'
testCompile 'junit:junit:4.12'
testCompile 'org.assertj:assertj-core:3.5.2'
testCompile 'org.apache.commons:commons-io:1.3.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,21 @@
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.InvocationTargetException;
import org.json.JSONException;


/**
* Created by rotemm on 10/10/2016.
*/
public class MethodInvocation {

public static Object invoke(Object map) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
return invoke(map, null);
}

public static Object invoke(Object map, Class<?> extendWith) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
JsonParser parser = getParserWithExtendedParsableTargetTypes(extendWith);
Invocation invocation = parser.parse(map, Invocation.class);
return invoke(invocation);
}

public static Object invoke(String invocationJson) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
public static Object invoke(String invocationJson) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, JSONException {
return invoke(invocationJson, null);
}

public static Object invoke(String invocationJson, Class<?> extendWith) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
JsonParser parser = getParserWithExtendedParsableTargetTypes(extendWith);
Invocation invocation = parser.parse(invocationJson, Invocation.class);
public static Object invoke(String invocationJson, Class<?> extendWith) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, JSONException {
JsonParser parser = new JsonParser();
Invocation invocation = new Invocation(parser.parse(invocationJson));
return invoke(invocation);
}

Expand All @@ -46,10 +37,4 @@ public static Object invoke(Invocation invocation) throws ClassNotFoundException
throw e;
}
}

public static JsonParser getParserWithExtendedParsableTargetTypes(Class<?> extendWith) {
JsonParser parser = new JsonParser();
parser.addMixInAnnotations(Target.class, extendWith);
return parser;
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
package com.wix.invoke.parser;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import org.json.JSONObject;
import org.json.JSONException;

/**
* Created by rotemm on 13/10/2016.
*/
public class JsonParser {

ObjectMapper objectMapper;
public JsonParser() {
objectMapper = new ObjectMapper();
}

public void addMixInAnnotations(Class<?> target, Class<?> mixinSource) {
objectMapper.addMixInAnnotations(target, mixinSource);
}

public <T> T parse(Object object, Class<T> valueType) {

try {
return objectMapper.convertValue(object, valueType);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
}

public <T> T parse(String jsonData, Class<T> valueType) {
public JSONObject parse(String jsonData) {
try {
return objectMapper.readValue(jsonData, valueType);
} catch (IOException e) {
JSONObject obj = new JSONObject(jsonData);
return obj;
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.wix.invoke.types;

import android.util.Log;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
;

import org.apache.commons.lang3.reflect.MethodUtils;

Expand All @@ -15,9 +13,7 @@
*/
public class ClassTarget extends Target {


@JsonCreator
public ClassTarget(@JsonProperty("value") Object value) {
public ClassTarget(Object value) {
super(value);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.wix.invoke.types;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.wix.invoke.MethodInvocation;
import com.wix.invoke.parser.JsonParser;

import java.util.Arrays;
import java.util.HashMap;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;

/**
* Created by rotemm on 10/10/2016.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class Invocation {
private Target target;
private String method;
Expand All @@ -26,6 +27,17 @@ public Invocation(Target target, String method, Object... args) {
this.args = args;
}

public Invocation(JSONObject json) throws JSONException {
this.target = Target.getTarget(json.getJSONObject("target"));
this.method = json.getString("method");
JSONArray args = json.getJSONArray("args");
try {
this.setArgs(args);
} catch (JSONException e) {
throw new RuntimeException("Unable to convert args");
}
}

public String getMethod() {
return method;
}
Expand All @@ -46,6 +58,43 @@ public Object[] getArgs() {
return args;
}

public void setArgs(JSONArray args) throws JSONException {
Object[] outputArgs = new Object[args.length()];
for (int i = 0; i < args.length(); i++) {
Object argument = null;
if (args.get(i).getClass() == "".getClass()) {
argument = args.get(i);
} else {
JSONObject jsonArgument = args.optJSONObject(i);
if (jsonArgument != null && jsonArgument.optString("type") != null) {
String type = jsonArgument.optString("type");
if (type.equals("Integer")) {
argument = jsonArgument.optInt("value");
} else if (type.equals("integer")) {
argument = jsonArgument.optInt("value");
} else if (type.equals("Float")) {
argument = Float.valueOf(jsonArgument.optString("value"));
} else if (type.equals("Double")) {
argument = jsonArgument.optDouble("value");
} else if (type.equals("String")) {
argument = jsonArgument.optString("value");
} else if (type.equals("Boolean")) {
argument = jsonArgument.optBoolean("value");
} else if (type.equals("boolean")) {
argument = jsonArgument.optBoolean("value");
} else if (type.equals("Invocation")) {
argument = new Invocation(jsonArgument.optJSONObject("value"));
} else {
throw new RuntimeException("Unhandled arg type" + type);
}
}
}
outputArgs[i] = argument;
}

this.args = outputArgs;
}

public void setArgs(Object[] args) {
for (int i = 0; i < args.length; i++) {
Object argument = args[i];
Expand All @@ -67,8 +116,8 @@ public void setArgs(Object[] args) {
} else if (type.equals("boolean")) {
argument = ((Boolean) value).booleanValue();
} else if (type.equals("Invocation")) {
JsonParser parser = MethodInvocation.getParserWithExtendedParsableTargetTypes(null);
argument = parser.parse(value, Invocation.class);
JsonParser parser = new JsonParser();
argument = parser.parse((String)value);
} else {
throw new RuntimeException("Unhandled arg type" + type);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package com.wix.invoke.types;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import org.apache.commons.lang3.reflect.MethodUtils;

import java.lang.reflect.InvocationTargetException;
Expand All @@ -12,8 +9,7 @@
*/
public class InvocationTarget extends Target {

@JsonCreator
public InvocationTarget(@JsonProperty("value") Invocation value) {
public InvocationTarget(Invocation value) {
super(value);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.wix.invoke.types;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import org.apache.commons.lang3.reflect.MethodUtils;

Expand All @@ -13,8 +11,7 @@

public class ObjectInstanceTarget extends Target {

@JsonCreator
public ObjectInstanceTarget(@JsonProperty("value") Object value) {
public ObjectInstanceTarget(Object value) {
super(value);
}

Expand Down
32 changes: 20 additions & 12 deletions detox/android/detox/src/main/java/com/wix/invoke/types/Target.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
package com.wix.invoke.types;


import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import java.lang.reflect.InvocationTargetException;
import org.json.JSONObject;
import org.json.JSONException;

/**
* Created by rotemm on 10/10/2016.
*/

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = ClassTarget.class, name = "Class"),
@JsonSubTypes.Type(value = InvocationTarget.class, name = "Invocation"),
@JsonSubTypes.Type(value = ObjectInstanceTarget.class, name = "Espresso"),
})
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class Target {

Object value;

public static Target getTarget(JSONObject target) throws JSONException {
String type = target.getString("type");

if (type.equals("Invocation")) {
JSONObject objectValue = target.getJSONObject("value");
return new InvocationTarget(new Invocation(objectValue));
}

if (type.equals("Espresso")) {
String stringValue = target.getString("value");
return new ObjectInstanceTarget(stringValue);
}

// Default to Class
String value = target.getString("value");
return new ClassTarget(value);
}

public Target(Object value) {
this.value = value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import org.junit.Test;
import static org.assertj.core.api.Java6Assertions.assertThat;
import org.json.JSONObject;
import org.json.JSONException;

/**
* Created by rotemm on 13/10/2016.
Expand Down Expand Up @@ -60,6 +62,12 @@ public void fromJsonTargetInvocationEspressoDetox() {

public Invocation parse(String filePath) {
String jsonData = TestUtils.jsonFileToString(filePath);
return new JsonParser().parse(jsonData, Invocation.class);
JSONObject json = new JsonParser().parse(jsonData);
try {
return new Invocation(json);
} catch (JSONException e) {
System.err.println("Could not parse json, got error: " + e.getMessage());
return new Invocation();
}
}
}
3 changes: 3 additions & 0 deletions scripts/ci.android.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

$(dirname "$0")/ci.sh

pushd detox/android
./gradlew test
popd
#echo no | "$ANDROID_HOME"/tools/bin/avdmanager create avd --force --name Nexus_5X_API_26 --abi armeabi-v7a --device "Nexus 5X" -k system-images;android-26;default;armeabi-v7a
#pushd detox/test
#npm run build:android
Expand Down

0 comments on commit fc6a1a2

Please sign in to comment.