com.magicsoftbay.qbuildersandroid.visitors.ContextualNodeVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of q-builders-android Show documentation
Show all versions of q-builders-android Show documentation
RESTful search query builder for Android
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);
}
}
}