All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.rutledgepaulv.qbuilders.delegates.concrete.ConditionPropertyDelegate Maven / Gradle / Ivy

package com.github.rutledgepaulv.qbuilders.delegates.concrete;

import com.github.rutledgepaulv.qbuilders.builders.QBuilder;
import com.github.rutledgepaulv.qbuilders.conditions.Condition;
import com.github.rutledgepaulv.qbuilders.delegates.virtual.PropertyDelegate;
import com.github.rutledgepaulv.qbuilders.nodes.*;
import com.github.rutledgepaulv.qbuilders.operators.ComparisonOperator;
import com.github.rutledgepaulv.qbuilders.properties.concrete.ConditionProperty;
import com.github.rutledgepaulv.qbuilders.structures.FieldPath;
import com.github.rutledgepaulv.qbuilders.visitors.AbstractVoidContextNodeVisitor;

import java.util.Collections;

public final class ConditionPropertyDelegate, S extends QBuilder>
        extends PropertyDelegate implements ConditionProperty {

    public ConditionPropertyDelegate(FieldPath field, T canonical) {
        super(field, canonical);
    }

    @Override
    public Condition any(Condition condition) {

        final LogicalNode root = ((ConditionDelegate) condition).getRootNode();

        // prepend this field to all of the fields in the subtree
        root.visit(new NamespacingVisitor(getField()));

        return condition(getField(), ComparisonOperator.SUB_CONDITION_ANY, Collections.singleton(condition));
    }

    private class NamespacingVisitor extends AbstractVoidContextNodeVisitor {

        private FieldPath parent;

        public NamespacingVisitor(FieldPath parent) {
            this.parent = parent;
        }

        @Override
        protected Void visit(AndNode node) {
            node.getChildren().stream().forEach(this::visitAny);
            return null;
        }

        @Override
        protected Void visit(OrNode node) {
            node.getChildren().stream().forEach(this::visitAny);
            return null;
        }

        @Override
        protected Void visit(ComparisonNode node) {
            node.setField(node.getField().prepend(parent));
            return null;
        }
    }

}