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

com.magicsoftbay.qbuildersandroid.visitors.ContextualNodeVisitor Maven / Gradle / Ivy

The newest version!
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 MAGIC SOFTWARE BAY SRL
 * Copyright (c) 2016 Paul Rutledge 
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies
 * or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.magicsoftbay.qbuildersandroid.visitors;


import com.magicsoftbay.qbuildersandroid.conditions.Condition;
import com.magicsoftbay.qbuildersandroid.nodes.AbstractNode;
import com.magicsoftbay.qbuildersandroid.nodes.AndNode;
import com.magicsoftbay.qbuildersandroid.nodes.ComparisonNode;
import com.magicsoftbay.qbuildersandroid.nodes.LogicalNode;
import com.magicsoftbay.qbuildersandroid.nodes.OrNode;
import com.magicsoftbay.qbuildersandroid.operators.ComparisonOperator;

import java.util.Collection;

/**
 * @author Paul Rutledge 
 * @author Clivens Petit 
 */
@SuppressWarnings("ConstantConditions")
public abstract class ContextualNodeVisitor {

    protected abstract T visit(AndNode node, S context);

    protected abstract T visit(OrNode node, S context);

    protected abstract T visit(ComparisonNode node, S context);

    /**
     * Build a comparison node value into a visited value so that
     * it can be composed into the larger query being built.
     *
     * @param node The node with a condition argument to build into a visited value.
     * @return The visited value.
     */
    protected T condition(ComparisonNode node, S context) {
        if (!node.getOperator().equals(ComparisonOperator.SUB_CONDITION_ANY)) {
            throw new IllegalArgumentException("You can only build a condition for sub-condition operator nodes.");
        }

        Object sub = node.getValues().iterator().next();

        // support either submitting a tree node in which case handle visiting it for
        // them, or submit a Condition representing a wrapper around that tree in which
        // case visit it with this visitor
        if (sub instanceof AbstractNode) {
            return visitAny((AbstractNode) sub, context);
        } else if (sub instanceof Condition) {
            return ((Condition) sub).query(this, context);
        } else {
            throw new IllegalArgumentException("Unknown node value type for subquery.");
        }

    }

    protected Object single(Collection values) {
        if (!values.isEmpty()) {
            return values.iterator().next();
        } else {
            throw new IllegalArgumentException("You must provide a non-null query value for the condition.");
        }
    }

    public final T visitAny(AbstractNode node, S context) {
        // skip straight to the children if it's a logical node with one member
        if (node instanceof LogicalNode) {
            LogicalNode logical = (LogicalNode) node;
            if (logical.getChildren().size() == 1) {
                return visitAny(logical.getChildren().get(0), context);
            }
        }

        if (node instanceof AndNode) {
            return visit((AndNode) node, context);
        } else if (node instanceof OrNode) {
            return visit((OrNode) node, context);
        } else {
            return visit((ComparisonNode) node, context);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy