浏览代码

Start writing type testers

Sam Jaffe 6 年之前
父节点
当前提交
60375294e7

+ 46 - 1
src/main/lombok/org/leumasjaffe/json/schema/factory/SchemaFactory.java

@@ -1,6 +1,7 @@
 package org.leumasjaffe.json.schema.factory;
 
 import java.util.List;
+import java.util.function.Predicate;
 import java.util.regex.Pattern;
 
 import org.leumasjaffe.json.JsonHelper;
@@ -9,8 +10,52 @@ import org.leumasjaffe.json.schema.Tester;
 import org.leumasjaffe.json.schema.tester.FixedTester;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeType;
 
-public class SchemaFactory {	
+import lombok.AllArgsConstructor;
+
+public class SchemaFactory {
+	static final JsonNodeType[] ANY = {
+			JsonNodeType.ARRAY, JsonNodeType.OBJECT, JsonNodeType.STRING,
+			JsonNodeType.NUMBER, JsonNodeType.BOOLEAN, JsonNodeType.NULL
+	};
+	
+	@AllArgsConstructor
+	static final class SimpleTester implements Tester {
+		JsonNodeType type;
+		Predicate<JsonNode> acceptor;
+		
+		@Override
+		public JsonNodeType[] acceptedTypes() {
+			return new JsonNodeType[]{ type };
+		}
+		
+		@Override
+		public boolean accepts(JsonNode node) {
+			return acceptor.test(node);
+		}
+	}
+	
+	@AllArgsConstructor
+	static final class MultiTypedTester implements Tester {
+		JsonNodeType[] types;
+		Predicate<JsonNode> acceptor;
+		
+		public MultiTypedTester(Predicate<JsonNode> acceptor, JsonNodeType...types) {
+			this(types, acceptor);
+		}
+		
+		@Override
+		public JsonNodeType[] acceptedTypes() {
+			return types;
+		}
+		
+		@Override
+		public boolean accepts(JsonNode node) {
+			return acceptor.test(node);
+		}
+	}
+	
 	public final Tester create(final JsonNode object) {
 		switch (object.getNodeType()) {
 		case BOOLEAN:

+ 8 - 4
src/main/lombok/org/leumasjaffe/json/schema/factory/SchemaV6Factory.java

@@ -1,5 +1,6 @@
 package org.leumasjaffe.json.schema.factory;
 
+import java.util.List;
 import java.util.function.Predicate;
 
 import org.leumasjaffe.json.JsonHelper;
@@ -46,7 +47,7 @@ class SchemaV6Factory extends SchemaFactory {
 		case "exclusiveMinimum": return new NumberTester(d -> d > value.asDouble());
 		case "maxLength": return new SizeTester(JsonNodeType.STRING, i -> i < value.asInt());
 		case "minLength": return new SizeTester(JsonNodeType.STRING, i -> i >= value.asInt(0));
-		case "pattern": return j -> j.isTextual() && j.asText().matches(value.asText());
+		case "pattern": return new SimpleTester(JsonNodeType.STRING, j -> j.asText().matches(value.asText()));
 		case "additionalItems": return new AllItemsTester(JsonNodeType.ARRAY, create(value));
 		case "items": return value.isArray() ? new ItemsTester(createArray(value)) : new AllItemsTester(JsonNodeType.ARRAY, create(value));
 		case "maxItems": return new SizeTester(JsonNodeType.ARRAY, i -> i < value.asInt());
@@ -55,7 +56,10 @@ class SchemaV6Factory extends SchemaFactory {
 		case "contains": return new ContainsTester(create(value));
 		case "maxProperties": return new SizeTester(JsonNodeType.OBJECT, i -> i < value.asInt());
 		case "minProperties": return new SizeTester(JsonNodeType.OBJECT, i -> i >= value.asInt(0));
-		case "required": return json -> JsonHelper.toArray(value, JsonNode::asText).stream().allMatch(json::has);
+		case "required": {
+			final List<String> reqKeys = JsonHelper.toArray(value, JsonNode::asText);
+			return new SimpleTester(JsonNodeType.OBJECT, json -> reqKeys.stream().allMatch(json::has));
+		}
 		case "additionalProperties": return new AllItemsTester(JsonNodeType.OBJECT, create(value));
 		// case "definitions": ; // TODO Implement definitions creation
 		case "properties": return new PropertyTester(JsonHelper.values(value,
@@ -64,8 +68,8 @@ class SchemaV6Factory extends SchemaFactory {
 				(k, v) -> new PropertyTester.Pair(stringMatches(k), create(v))));
 		// case "dependencies": ; // TODO Implement array(required) and object(schema) versions
 		case "propertyNames": return new PropertyNameTester(create(value));
-		case "const": return value::equals;
-		case "enum": return new AnyOfTester(JsonHelper.toArray(value, v -> (Tester) v::equals));
+		case "const": return new MultiTypedTester(ANY, value::equals);
+		case "enum": return new AnyOfTester(JsonHelper.toArray(value, v -> new MultiTypedTester(ANY, v::equals)));
 		case "type": return TypeTester.fromType(value.asText());
 		case "format": return FormatTester.forCode(value.asText());
 		case "allOf": return new AllOfTester(createArray(value));