PandaLib/pandalib-permissions/src/main/java/fr/pandacube/lib/permissions/PermissionExpressionParser.java

130 lines
4.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package fr.pandacube.lib.permissions;
import java.util.Iterator;
import java.util.function.Function;
import com.fathzer.soft.javaluator.AbstractEvaluator;
import com.fathzer.soft.javaluator.BracketPair;
import com.fathzer.soft.javaluator.Constant;
import com.fathzer.soft.javaluator.Operator;
import com.fathzer.soft.javaluator.Operator.Associativity;
import com.fathzer.soft.javaluator.Parameters;
public class PermissionExpressionParser {
private static final PermissionEvaluator PERMISSION_EVALUATOR = new PermissionEvaluator();
public static boolean evaluate(String permString, LitteralPermissionTester permTester) {
try {
return PERMISSION_EVALUATOR.evaluate(permString, permTester);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Cant evaluate the provided permission expression: '" + permString + "'", e);
}
}
public interface LitteralPermissionTester extends Function<String, Boolean> { }
private static class PermissionEvaluator extends AbstractEvaluator<Boolean> {
private static final Operator NOT = new Operator("!", 1, Associativity.LEFT, 3);
private static final Operator AND = new Operator("&&", 2, Associativity.LEFT, 2);
private static final Operator OR = new Operator("||", 2, Associativity.LEFT, 1);
private static final Constant TRUE = new Constant("true");
private static final Constant FALSE = new Constant("false");
private static final Parameters PARAMETERS;
static {
PARAMETERS = new Parameters();
PARAMETERS.add(NOT);
PARAMETERS.add(AND);
PARAMETERS.add(OR);
PARAMETERS.add(TRUE);
PARAMETERS.add(FALSE);
PARAMETERS.addExpressionBracket(BracketPair.PARENTHESES);
}
public PermissionEvaluator() {
super(PARAMETERS);
}
@Override
protected Boolean toValue(String literal, Object evaluationContext) {
if (literal.contains(" ") || literal.contains("|") || literal.contains("&"))
throw new IllegalArgumentException("Unable to parse the following part of permission expression as one permission node: '" + literal + "'");
return evaluationContext instanceof LitteralPermissionTester pt ? pt.apply(literal) : false;
}
@Override
protected Boolean evaluate(Operator operator, Iterator<Boolean> operands, Object evaluationContext) {
if (operator == NOT) {
return !operands.next();
} else if (operator == OR) {
Boolean o1 = operands.next();
Boolean o2 = operands.next();
return o1 || o2;
} else if (operator == AND) {
Boolean o1 = operands.next();
Boolean o2 = operands.next();
return o1 && o2;
} else {
return super.evaluate(operator, operands, evaluationContext);
}
}
@Override
protected Boolean evaluate(Constant constant, Object evaluationContext) {
if (constant == TRUE)
return true;
if (constant == FALSE)
return false;
return super.evaluate(constant, evaluationContext);
}
}
/* TODO move to test code
public static void main(String[] args) {
java.util.List<String> pList = java.util.Arrays.asList("p1.cmd", "p1.toto", "p2.lol");
LitteralPermissionTester tester = p -> pList.contains(p);
for (String permExpr : java.util.Arrays.asList(
"p1.cmd", // true
"p1.notexist", // false
"p2lol.lol", // false
"!p1.notexist", // true
"!p1.cmd", // false
"p1.cmd!", // false
"p1.cmd! p2.lol", // exception
"p1.cmd || p1.toto", // true || true == true
"p1.cmd || p1.notexist", // true || false == true
"p1.fefef || p2.lol", // false || true == true
"p1.fefef || p2.lolilol", // false || false == false
"p1.cmd && p1.toto", // true && true == true
"p1.cmd && p1.notexist", // true && false == false
"p1.fefef && p2.lol", // false && true == false
"p1.fefef && p2.lolilol", // false && false == false
"p1.cmd && !p1.toto ", // true && !true == false
" !p1.cmd && p1.toto", // !true && true == false
"!p1.cmd & p1.toto", // exception
"!p1.cmd | p1.toto", // exception
"p1.not exist" // exception
)) {
try {
System.out.println(permExpr + " -> " + evaluate(permExpr, tester));
} catch (Exception e) {
e.printStackTrace();
}
}
}
*/
}