Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ subprojects {
compile project.deps.jackson.databind
compile project.deps.logs.slf4j
compile project.deps.logs.logback
compile project.deps.tests.jsonAssert

compileOnly project.deps.vertx.codegen
compileOnly project.deps.lombok
annotationProcessor project.deps.lombok

testCompile project.deps.tests.junit
testCompile project.deps.tests.jsonAssert
testCompile project.deps.vertx.junit
testCompileOnly project.deps.lombok
testAnnotationProcessor project.deps.lombok
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.nubeiot.core.exceptions;

import com.nubeiot.core.utils.Strings;

import lombok.Builder;

@Builder(builderClassName = "Builder")
public class ValidationError {

static final NubeException.ErrorCode DEFAULT_ERROR_CODE = NubeException.ErrorCode.INVALID_ARGUMENT;
static final String DEFAULT_ERROR_TYPE = "ValidationError";

@lombok.Builder.Default
private NubeException.ErrorCode errorCode = DEFAULT_ERROR_CODE;
@lombok.Builder.Default
private String errorType = DEFAULT_ERROR_TYPE;
@lombok.Builder.Default
private String value = "";
private String message;

public NubeException execute() {
String errorMessage = (((Strings.isNotBlank(errorType) ? errorType + ": " : "") + value).trim() + " " + message)
.trim();
return new NubeException(errorCode, errorMessage);
}

}
121 changes: 121 additions & 0 deletions core/base/src/main/java/com/nubeiot/core/utils/JsonUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.nubeiot.core.utils;

import java.util.Map;
import java.util.function.BiFunction;

import org.skyscreamer.jsonassert.JSONCompare;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

public class JsonUtils {

/**
* JsonObject @source gets merge with the JsonObject @defaultValue.
*/
public static BiFunction<Object, Object, Object> mergeJsonObjectFunc = (source, defaultValue) -> {
((JsonObject) defaultValue).forEach(
(defaultValueMap) -> iterateMergeFunction((JsonObject) source, defaultValueMap));
return source;
};

public static Object getObject(JsonObject s, String field, Object defaultValue) {
Object output = getObject(s, field);
if (output == null) {
output = defaultValue;
}
return output;
}

public static Object getObject(JsonObject s, String field) {
String[] fields;
if (Strings.isNotBlank(field)) {
fields = field.split("\\.");
} else {
return s;
}

Object output = null;

try {
for (int i = 0; i < fields.length - 1; i++) {
s = s.getJsonObject(fields[i]);
}
output = s.getValue(fields[fields.length - 1]);
} catch (NullPointerException | ClassCastException ignored) {
}
return output;
}

public static boolean compareJsonObject(JsonObject expected, JsonObject actual) {
if (expected == null && actual == null) {
return true;
} else if (expected == null || actual == null) {
return false;
}

JSONCompareResult result = null;
try {
result = JSONCompare.compareJSON(expected.encode(), actual.encode(), JSONCompareMode.STRICT);
} catch (org.json.JSONException e) {
e.printStackTrace();
}
return result != null && result.passed();
}

private static void iterateMergeFunction(JsonObject source, Map.Entry<String, Object> defaultValueMap) {
Object defaultValue = defaultValueMap.getValue();
String defaultKey = defaultValueMap.getKey();
JsonObject sourceObject = source;
Object sourceValue = sourceObject.getValue(defaultKey);
if (defaultValue instanceof JsonObject && (sourceValue instanceof JsonObject || sourceValue == null)) {
if (sourceValue == null) {
sourceObject.put(defaultKey, new JsonObject());
}
sourceObject = sourceObject.getJsonObject(defaultKey);
for (Map.Entry<String, Object> defaultValueMapChild : (JsonObject) defaultValue) {
iterateMergeFunction(sourceObject, defaultValueMapChild);
}
} else if (defaultValue instanceof JsonArray && (sourceValue instanceof JsonArray || sourceValue == null)) {
if (sourceValue == null) {
sourceObject.put(defaultKey, new JsonArray());
}
JsonArray sourceArray = sourceObject.getJsonArray(defaultKey);
iterateJsonArrayMergeFunction(sourceArray, (JsonArray) defaultValue);
} else if (!(defaultValue instanceof Iterable) && !(sourceValue instanceof Iterable)) {
if (sourceValue == null) {
sourceObject.put(defaultKey, defaultValue);
}
}
}

private static void iterateJsonArrayMergeFunction(JsonArray sourceArray, JsonArray defaultValueArray) {
Object defaultValue = defaultValueArray.getValue(0);
if (defaultValue instanceof JsonObject) {
if (sourceArray.size() == 0) {
sourceArray.add(new JsonObject());
}
for (Object o : sourceArray) {
((JsonObject) defaultValue).forEach(
defaultValueMapChild -> iterateMergeFunction((JsonObject) o, defaultValueMapChild));
}
} else if (defaultValue instanceof JsonArray) {
if (sourceArray.size() == 0) {
sourceArray.add(new JsonArray());
}
for (Object o : sourceArray) {
if (o instanceof JsonArray) {
iterateJsonArrayMergeFunction((JsonArray) o, (JsonArray) defaultValue);
}
}
} else {
if (sourceArray.size() == 0) {
sourceArray.add(defaultValue);
}
}
}

}

113 changes: 113 additions & 0 deletions core/base/src/test/java/com/nubeiot/core/utils/JsonUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.nubeiot.core.utils;

import org.json.JSONException;
import org.junit.Assert;
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

public class JsonUtilsTest {

@Test
public void test_get_json_value() {
JsonObject jsonObject = new JsonObject().put("details", new JsonObject().put("first_name", "Shane")
.put("last_name", "Watson")
.put("club", new JsonArray().add(
"Sydney Sixers").add("RR")));
Assert.assertEquals(JsonUtils.getObject(jsonObject, "details").toString(),
"{\"first_name\":\"Shane\"," + "\"last_name\":\"Watson\",\"club\":[\"Sydney " +
"Sixers\",\"RR\"]}");
Assert.assertEquals(JsonUtils.getObject(jsonObject, "details.first_name"), "Shane");
Assert.assertEquals(JsonUtils.getObject(jsonObject, "details.last_name"), "Watson");
Assert.assertEquals(JsonUtils.getObject(jsonObject, "details.club").toString(), "[\"Sydney Sixers\",\"RR\"]");

Assert.assertNull(JsonUtils.getObject(jsonObject, "details.last_name.club"));
}

@Test
public void test_compareJsonObject_success() {
JsonObject actual = new JsonObject().put("details", new JsonObject().put("first_name", "Shane"));
JsonObject expected = new JsonObject().put("details", new JsonObject().put("first_name", "Shane"));

Assert.assertTrue(JsonUtils.compareJsonObject(expected, actual));
Assert.assertTrue(JsonUtils.compareJsonObject(null, null));
}

@Test
public void test_compareJsonObject_failure() {
JsonObject actual = new JsonObject().put("details", new JsonObject().put("first_name", "Shane"));
JsonObject expected = new JsonObject().put("details", new JsonObject());

Assert.assertFalse(JsonUtils.compareJsonObject(expected, actual));
Assert.assertFalse(JsonUtils.compareJsonObject(expected, null));
Assert.assertFalse(JsonUtils.compareJsonObject(null, actual));
}

@Test
public void test_mergeJsonObjectFunc1() throws JSONException {
JsonObject sourceJsonObject = new JsonObject().put("a", "10").put("d", new JsonArray());
JsonObject defaultJsonObject = new JsonObject().put("b", 20)
.put("c", new JsonObject().put("x", "2"))
.put("d", new JsonArray().add(new JsonObject().put("y", 3)));

JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject);
System.out.println(sourceJsonObject);
JSONAssert.assertEquals(sourceJsonObject.encode(),
"{\"a\":\"10\",\"d\":[{\"y\":3}],\"b\":20," + "\"c\":{\"x\":\"2\"}}", true);
}

@Test
public void test_mergeJsonObjectFunc2() throws JSONException {
JsonObject sourceJsonObject = new JsonObject().put("a", "10")
.put("d", new JsonArray().add(new JsonObject().put("z", 3)));
JsonObject defaultJsonObject = new JsonObject().put("b", 20)
.put("c", new JsonObject().put("x", "2"))
.put("d", new JsonArray().add(new JsonObject().put("y", 3)));

JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject);
System.out.println(sourceJsonObject);
JSONAssert.assertEquals(sourceJsonObject.encode(),
"{\"a\":\"10\",\"d\":[{\"z\":3,\"y\":3}],\"b\":20,\"c\":{\"x\":\"2\"}}", true);
}

@Test
public void test_mergeJsonObjectFunc3() throws JSONException {
JsonObject sourceJsonObject = new JsonObject().put("a", "10").put("d", new JsonArray());
JsonObject defaultJsonObject = new JsonObject().put("b", 20)
.put("c", new JsonObject().put("x", "2"))
.put("d", new JsonArray().add(new JsonArray().add("Hello")));

JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject);
System.out.println(sourceJsonObject);
JSONAssert.assertEquals(sourceJsonObject.encode(),
"{\"a\":\"10\",\"d\":[[\"Hello\"]],\"b\":20,\"c\":{\"x\":\"2\"}}", true);
}

@Test
public void test_mergeJsonObjectFunc4() throws JSONException {
JsonObject sourceJsonObject = new JsonObject().put("a", "10");
JsonObject defaultJsonObject = new JsonObject().put("b", 20)
.put("c", new JsonObject().put("x", "2"))
.put("d", new JsonArray().add("y"));

JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject);
System.out.println(sourceJsonObject);
JSONAssert.assertEquals(sourceJsonObject.encode(), "{\"a\":\"10\",\"b\":20,\"c\":{\"x\":\"2\"},\"d\":[\"y\"]}",
true);
}

@Test
public void test_mergeJsonObjectFunc5() throws JSONException {
JsonObject sourceJsonObject = new JsonObject().put("d",
new JsonArray().add(new JsonObject()).add(new JsonObject()));
JsonObject defaultJsonObject = new JsonObject().put("d", new JsonArray().add(
new JsonObject().put("x", new JsonArray().add("2"))));

JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject);
System.out.println(sourceJsonObject);
JSONAssert.assertEquals(sourceJsonObject.encode(), "{\"d\":[{\"x\":[\"2\"]},{\"x\":[\"2\"]}]}", true);
}

}
5 changes: 5 additions & 0 deletions core/validator/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dependencies {
compile project(':core:base')

testCompile project(':core:base').sourceSets.test.output
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.nubeiot.core.validator;

import com.nubeiot.core.exceptions.ValidationError;

public abstract class DataTypeValidation<T> implements Validation<T> {

protected abstract Class classType();

@Override
public ValidationResult validity(T s) {
if (classType().isInstance(s)) {
return ValidationResult.valid();
}

return ValidationResult.invalid(ValidationError.builder()
.value(s == null ? null : s.toString())
.message("is not the type of " + classType().getName()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.nubeiot.core.validator;

import com.nubeiot.core.utils.JsonUtils;
import com.nubeiot.core.utils.Strings;

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

public interface JsonValidation {

default Object get(Object data, String key) {
if (Strings.isBlank(key) || data instanceof JsonArray) {
return data;
}
if (!(data instanceof JsonObject)) {
return null;
}
return JsonUtils.getObject((JsonObject) data, key);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.nubeiot.core.validator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lombok.NonNull;

public class JsonValidationHolder<T> implements JsonValidation, ValidationHolder<T> {

protected Map<String, List<Validation<Object>>> validations = new HashMap<>();

@Override
public Map<String, List<Validation<Object>>> validations() {
return this.validations;
}

@Override
public ValidationHolder add(String field, @NonNull Validation<Object> validation) {
List<Validation<Object>> validationList = this.validations.get(field);
if (validationList == null) {
validationList = new ArrayList<>();
}
validationList.add(validation);
this.validations.put(field, validationList);
return this;
}

@Override
public Object get(Object data, String key) {
return JsonValidation.super.get(data, key);
}

}

Loading