Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The following format is expected to be supported. #1

Open
vampireslove opened this issue Mar 7, 2023 · 7 comments
Open

The following format is expected to be supported. #1

vampireslove opened this issue Mar 7, 2023 · 7 comments
Assignees

Comments

@vampireslove
Copy link
Contributor

vampireslove commented Mar 7, 2023

// {"name": "projectA"}
@test
public void testSimpleMatch() throws Exception {
String rule ="{\n" +
" "$and": [\n" +
" {\n" +
" "source": "weather2"\n" +
" }\n" +
" ]\n" +
"}";
System.out.println(rule);
Map<String,Object> mapData = new HashMap<>();
mapData.put("source","weather2");
ObjectMapper mapper = new ObjectMapper();
Predicate pred = factory.read(rule.getBytes());
boolean test = pred.test(mapData);
Assert.assertTrue(test);
}

thiagolvlsantos added a commit that referenced this issue Mar 7, 2023
thiagolvlsantos added a commit that referenced this issue Mar 7, 2023
@thiagolvlsantos
Copy link
Owner

thiagolvlsantos commented Mar 7, 2023

Hi @vampireslove,

First of all I appreciate your feedback, however, your example is not according to the BNF

{ 
	"<path1>" : { "<operator>": "<value> | @<path2>" } 
}

It lacks the operator which stands for the intention: to compare and check if the source assigned value is equals to weather2.

But, your example revealed a false positive which I fixed in 0.0.8-SNAPSHOT (current repo) and your example running sucessfully can be found at IssuesTest.java as:

// Issue: #1
	@Test
	public void testSimpleMatch() throws Exception {
		PredicateFactoryJson factory = new PredicateFactoryJson();
		Map<String, Object> mapData = new HashMap<>();
		String rule = null;

		// exact match
		rule = "{\n" + " \"$and\": [\n" + " {\n" + " \"source\": {\"$eq\":\"weather2\"}\n" + " }\n" + " ]\n" + "}";
		Predicate<Object> pred = factory.read(rule.getBytes());
		// positive test
		mapData.put("source", "weather2");
		Assert.assertTrue(pred.test(mapData));
		// negative test
		mapData.put("source", "weather3");
		Assert.assertFalse(pred.test(mapData));

		// example with contains 'weather'
		rule = "{\n" + " \"$and\": [\n" + " {\n" + " \"source\": {\"$contains\":\"weather\"}\n" + " }\n" + " ]\n" + "}";
		mapData.put("source", "weather2");
		pred = factory.read(rule.getBytes());
		Assert.assertTrue(pred.test(mapData));
		mapData.put("source", "weather3");
		Assert.assertTrue(pred.test(mapData));
		mapData.put("source", "anyvalue");
		Assert.assertFalse(pred.test(mapData));
	}

Best regards, Thiago.

@vampireslove
Copy link
Contributor Author

vampireslove commented Mar 9, 2023

Hi @thiagolvlsantos ,
Thank you for your reply. In the case of equals, you can omit the $eq operator, just to make the syntax a little bit cleaner.

  1. {"$and":[{"source":"weather2"}]} -- More concise
  2. {"$and":[{"source":{"$eq":"weather2"}}]} -- Stricter grammar

@vampireslove
Copy link
Contributor Author

vampireslove commented Mar 9, 2023

Modified io.github.thiagolvlsantos.json.predicate.impl.PredicateFactoryJson fields method 。

private void fields(String gap, List<IPredicate> result, String key, JsonNode value) {
	//This format {"xxx":"aa"} equivalent to {"xxx":{"$eq":"aa"}} 
	Iterator<Entry<String, JsonNode>> fs = value.fields();
	if(!fs.hasNext()){
               String op = "$eq";
		Class<? extends IPredicate> type = manager.get(op);
		JsonNode va = value;
		if (type == null) {
			throw new JsonPredicateException("Invalid group operator: " + op + " for " + va, null);
		}
		if (IPredicateValue.class.isAssignableFrom(type)) {
			fieldValue(gap, result, key, value, va, type);
		} else {
			throw new JsonPredicateException("Invalid group operator: " + op + " is not a value.", null);
		}
		return;
	}
	while (fs.hasNext()) {
		Entry<String, JsonNode> f = fs.next();
		String op = f.getKey();
		JsonNode va = f.getValue();
		Class<? extends IPredicate> type = manager.get(op);
		if (type == null) {
			throw new JsonPredicateException("Invalid group operator: " + op + " for " + va, null);
		}
		if (IPredicateValue.class.isAssignableFrom(type)) {
			fieldValue(gap, result, key, value, va, type);
		} else {
			throw new JsonPredicateException("Invalid group operator: " + op + " is not a value.", null);
		}
	}
}

@thiagolvlsantos
Copy link
Owner

Hi @vampireslove,

Now I can see your point, in fact these kind of syntactic suggar are very welcome.

I will incorporate your suggestion/code and later try refactor it to a more general rewriting engine in order to "sanitize expressions" to the stricter form. I mean, any reduced or complex expression can be rewritten in terms of the expected "normal form"; it seams to be the case. With this abstraction anyone can include or rewrite as wish the accepted expressions.

[]'s

@thiagolvlsantos
Copy link
Owner

I´ll also include a new README section to it when it`s done.

Ps. Keeping this issue open until the refactoring is done.

[]'s

@vampireslove
Copy link
Contributor Author

@thiagolvlsantos Looking forward to the idea ...

@thiagolvlsantos thiagolvlsantos self-assigned this Mar 10, 2023
@thiagolvlsantos thiagolvlsantos added this to the Release: 0.0.8 milestone Mar 10, 2023
@thiagolvlsantos
Copy link
Owner

thiagolvlsantos commented Mar 11, 2023

Hi @vampireslove,

I made it very simpler from start: only call rewrite activated for missing operators add it as "$eq".

In the future it can be done in advance just after parsing the JSON, something like: sanitizing the rule before application.

However this approach could also bring disvantages, the user could not know exactly which rule is being performed. Something like not writing HTML properly where browsers have different behaviors, usualy is prefered to abort in order avoid missunderstandings, this approach is used by the XML lib XOM, for example.

Ps. If you consider it`s enough by now, please close the issue.

Best regards, Thiago.

thiagolvlsantos added a commit that referenced this issue Mar 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants