我知道我来晚了,但今天我不得不解决同样的问题,我发现这个问题没有真正的解决方案或解决方法。
但是,我设法使用以下结构“代理”递归:
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Expression
{
Node value();
SubExpression[] subExpressions() default {};
}
@Retention(RetentionPolicy.RUNTIME)
@interface SubExpression
{
String id();
String operator();
Node[] nodes();
}
@Retention(RetentionPolicy.RUNTIME)
@interface Node
{
String subExpression() default "";
String name() default "";
String value() default "";
}
@Expression(
value = @Node(subExpression = "1"),
subExpressions = {
@SubExpression(id = "1", operator = "AND",
nodes = {
@Node(name = "responsible", value = "foo"),
@Node(subExpression = "2")
}),
@SubExpression(id = "2", operator = "OR",
nodes = {
@Node(name = "status", value = "closed"),
@Node(name = "visibility", value = "public")
}),
})
public class TestAnnotationRecursion
{
public static void main(String[] args)
{
Expression expression = TestAnnotationRecursion.class.getAnnotation(Expression.class);
Map<String, SubExpression> subExpressionMap = Arrays.stream(expression.subExpressions())
.collect(Collectors.toMap(x -> x.id(), x -> x));
String result = parseNode(expression.value(), subExpressionMap);
System.out.println(result);
}
public static String parseNode(Node node, Map<String, SubExpression> subExpressionMap)
{
String subExpressionId = node.subExpression();
if(subExpressionId.isEmpty())
{
return node.name() + " = '" + node.value() + "'";
}
SubExpression subExpression = subExpressionMap.get(subExpressionId);
return Arrays.stream(subExpression.nodes())
.map(n -> parseNode(n, subExpressionMap))
.collect(Collectors.joining(" " + subExpression.operator() + " ", "(", ")"));
}
}
这评估为:
(responsible = 'foo' AND (status = 'closed' OR visibility = 'public'))
尽管它的可读性值得怀疑,但我认为这是在不允许显式递归时我们可以实现的最佳折衷方案。