com.github.rutledgepaulv.qbuilders.visitors.MongoVisitor.java Source code

Java tutorial

Introduction

Here is the source code for com.github.rutledgepaulv.qbuilders.visitors.MongoVisitor.java

Source

/*
 *
 *  *  com.github.rutledgepaulv.qbuilders.visitors.MongoVisitor
 *  *  *
 *  *  * Copyright (C) 2016 Paul Rutledge <paul.v.rutledge@gmail.com>
 *  *  *
 *  *  * This software may be modified and distributed under the terms
 *  *  * of the MIT license.  See the LICENSE file for details.
 *  *
 *
 */

package com.github.rutledgepaulv.qbuilders.visitors;

import com.github.rutledgepaulv.qbuilders.nodes.AndNode;
import com.github.rutledgepaulv.qbuilders.nodes.ComparisonNode;
import com.github.rutledgepaulv.qbuilders.nodes.OrNode;
import com.github.rutledgepaulv.qbuilders.operators.ComparisonOperator;
import org.springframework.data.mongodb.core.query.Criteria;

import java.sql.Date;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.springframework.data.mongodb.core.query.Criteria.where;

@SuppressWarnings("WeakerAccess")
public class MongoVisitor extends AbstractVoidContextNodeVisitor<Criteria> {

    protected final Function<Object, Object> normalizer;

    public MongoVisitor() {
        this(new DefaultNormalizer());
    }

    public MongoVisitor(Function<Object, Object> normalizer) {
        this.normalizer = normalizer;
    }

    @Override
    protected Criteria visit(AndNode node) {
        Criteria criteria = new Criteria();
        List<Criteria> children = node.getChildren().stream().map(this::visitAny).collect(Collectors.toList());
        return criteria.andOperator(children.toArray(new Criteria[children.size()]));
    }

    @Override
    protected Criteria visit(OrNode node) {
        Criteria criteria = new Criteria();
        List<Criteria> children = node.getChildren().stream().map(this::visitAny).collect(Collectors.toList());
        return criteria.orOperator(children.toArray(new Criteria[children.size()]));
    }

    @Override
    protected Criteria visit(ComparisonNode node) {

        ComparisonOperator operator = node.getOperator();

        Collection<?> values = node.getValues().stream().map(normalizer).collect(Collectors.toList());
        String field = node.getField().asKey();

        if (ComparisonOperator.EQ.equals(operator)) {
            return where(field).is(single(values));
        } else if (ComparisonOperator.NE.equals(operator)) {
            return where(field).ne(single(values));
        } else if (ComparisonOperator.EX.equals(operator)) {
            return where(field).exists((Boolean) single(values));
        } else if (ComparisonOperator.GT.equals(operator)) {
            return where(field).gt(single(values));
        } else if (ComparisonOperator.LT.equals(operator)) {
            return where(field).lt(single(values));
        } else if (ComparisonOperator.GTE.equals(operator)) {
            return where(field).gte(single(values));
        } else if (ComparisonOperator.LTE.equals(operator)) {
            return where(field).lte(single(values));
        } else if (ComparisonOperator.IN.equals(operator)) {
            return where(field).in(values);
        } else if (ComparisonOperator.NIN.equals(operator)) {
            return where(field).nin(values);
        } else if (ComparisonOperator.RE.equals(operator)) {
            return where(field).regex((String) single(values));
        } else if (ComparisonOperator.SUB_CONDITION_ANY.equals(operator)) {
            return where(field).elemMatch(condition(node));
        }

        throw new UnsupportedOperationException("This visitor does not support the operator " + operator + ".");
    }

    protected static class DefaultNormalizer implements Function<Object, Object> {

        @Override
        public Object apply(Object o) {
            if (o instanceof Instant) {
                return Date.from((Instant) o);
            }
            return o;
        }

    }

}