fr.gouv.vitam.query.parser.MdQueryParser.java Source code

Java tutorial

Introduction

Here is the source code for fr.gouv.vitam.query.parser.MdQueryParser.java

Source

/**
 * This file is part of Vitam Project.
 *
 * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
 * COPYRIGHT.txt in the distribution for a full listing of individual contributors.
 *
 * All Vitam Project is free software: you can redistribute it and/or modify it under the terms of
 * the GNU General Public License as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * Vitam is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with Vitam . If not, see
 * <http://www.gnu.org/licenses/>.
 */
package fr.gouv.vitam.query.parser;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import org.bson.BSON;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import fr.gouv.vitam.query.parser.ParserTokens.RANGEARGS;
import fr.gouv.vitam.query.parser.ParserTokens.REQUEST;
import fr.gouv.vitam.utils.exception.InvalidParseOperationException;
import fr.gouv.vitam.utils.json.JsonHandler;
import fr.gouv.vitam.utils.logging.VitamLogger;
import fr.gouv.vitam.utils.logging.VitamLoggerFactory;

/**
 * Version using MongoDB
 *
 * @author "Frederic Bregier"
 *
 */
public class MdQueryParser extends AbstractQueryParser {
    private static final VitamLogger LOGGER = VitamLoggerFactory.getInstance(MdQueryParser.class);

    /**
     * @param simul
     */
    public MdQueryParser(final boolean simul) {
        super(simul);
        usingMongoDb = true;
    }

    /*
     * In MongoDB : find(Query, Projection).sort(SortFilter).skip(SkipFilter).limit(LimitFilter);
     * In addition, one shall limit the scan by: find(Query, Projection)._addSpecial( "$maxscan", highlimit
     * ).sort(SortFilter).skip(SkipFilter).limit(LimitFilter);
     */

    @Override
    protected void checkRootTypeRequest(final TypeRequest tr, final JsonNode command, final int prevDepth)
            throws InvalidParseOperationException {
        if (tr.relativedepth > 1 || lastDepth - prevDepth > 1) {
            // MongoDB not allowed
            LOGGER.debug("ES only: {}", command);
            throw new InvalidParseOperationException(
                    "Command not allowed with MongoDB while Depth step: " + (lastDepth - prevDepth) + ":"
                            + lastDepth + ":" + prevDepth + ":" + tr.relativedepth + " " + tr);
        }
    }

    /**
     * $size : { name : length }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeSize(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        final Entry<String, JsonNode> element = JsonHandler.checkUnicity(refCommand, command);
        tr0.requestModel = JsonHandler.createObjectNode();
        tr0.requestModel.putObject(element.getKey()).set(refCommand, element.getValue());
    }

    /**
     * $gt : { name : value }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeCompare(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        final Entry<String, JsonNode> element = JsonHandler.checkUnicity(refCommand, command);
        tr0.requestModel = JsonHandler.createObjectNode();
        tr0.requestModel.putObject(element.getKey()).set(refCommand, element.getValue());
    }

    /**
     * $flt : { $fields : [ name1, name2 ], $like : like_text }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeXlt(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        throw new InvalidParseOperationException("Command not allowed with MongoDB: " + refCommand);
    }

    /**
     * $search : { name : searchParameter }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeSearch(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        throw new InvalidParseOperationException("Command not allowed with MongoDB: " + refCommand);
    }

    /**
     * $match : { name : words, $max_expansions : n }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeMatch(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        throw new InvalidParseOperationException("Command not allowed with MongoDB: " + refCommand);
    }

    /**
     * $in : { name : [ value1, value2, ... ] }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeIn(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        final Entry<String, JsonNode> element = JsonHandler.checkUnicity(refCommand, command);
        tr0.requestModel = JsonHandler.createObjectNode();
        final ArrayNode objectMD = tr0.requestModel.putObject(element.getKey()).putArray(refCommand);
        for (final JsonNode value : element.getValue()) {
            objectMD.add(value);
        }
    }

    /**
     * $range : { name : { $gte : value, $lte : value } }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeRange(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        final Entry<String, JsonNode> element = JsonHandler.checkUnicity(refCommand, command);
        tr0.requestModel = JsonHandler.createObjectNode();
        final ObjectNode objectMD = tr0.requestModel.putObject(element.getKey());
        for (final Iterator<Entry<String, JsonNode>> iterator = element.getValue().fields(); iterator.hasNext();) {
            final Entry<String, JsonNode> requestItem = iterator.next();
            RANGEARGS arg = null;
            try {
                final String key = requestItem.getKey();
                if (key.startsWith("$")) {
                    arg = RANGEARGS.valueOf(requestItem.getKey().substring(1));
                } else {
                    throw new InvalidParseOperationException("Invalid Range query command: " + requestItem);
                }
            } catch (final IllegalArgumentException e) {
                throw new InvalidParseOperationException("Invalid Range query command: " + requestItem, e);
            }
            objectMD.set(arg.exactToken(), requestItem.getValue());
        }
    }

    /**
     * $regex : { name : regex }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeRegex(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        final Entry<String, JsonNode> entry = JsonHandler.checkUnicity(refCommand, command);
        tr0.requestModel = JsonHandler.createObjectNode();
        tr0.requestModel.putObject(entry.getKey()).set(refCommand, entry.getValue());
    }

    /**
     * $term : { name : term, name : term }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeTerm(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        tr0.requestModel = JsonHandler.createObjectNode();
        tr0.requestModel.setAll((ObjectNode) command);
    }

    /**
     * $wildcard : { name : regex }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeWildcard(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        final Entry<String, JsonNode> entry = JsonHandler.checkUnicity(refCommand, command);
        tr0.requestModel = JsonHandler.createObjectNode();
        String value = entry.getValue().asText();
        value = value.replace('?', '.').replace("*", ".*");
        tr0.requestModel.putObject(entry.getKey()).put(REQUEST.regex.exactToken(), value);
    }

    /**
     * $eq : { name : value }
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeEq(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        final Entry<String, JsonNode> entry = JsonHandler.checkUnicity(refCommand, command);
        tr0.requestModel = JsonHandler.createObjectNode();
        if (req == REQUEST.ne) {
            tr0.requestModel.putObject(entry.getKey()).set(refCommand, entry.getValue());
        } else {
            tr0.requestModel.set(entry.getKey(), entry.getValue());
        }
    }

    /**
     * $exists : name
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeExistsMissing(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        // only fieldname
        final String fieldname = command.asText();
        tr0.requestModel = JsonHandler.createObjectNode();
        tr0.requestModel.putObject(fieldname).put(REQUEST.exists.exactToken(), req == REQUEST.exists);
    }

    /**
     * $isNull : name
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeIsNull(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        // only fieldname
        final String fieldname = command.asText();
        tr0.requestModel = JsonHandler.createObjectNode();
        tr0.requestModel.putObject(fieldname).put("$type", BSON.NULL);
    }

    /**
     * $and : [ expression1, expression2, ... ]
     *
     * @param refCommand
     * @param command
     * @param tr0
     * @param req
     * @throws InvalidParseOperationException
     */
    @Override
    protected void analyzeAndNotNorOr(final String refCommand, final JsonNode command, final TypeRequest tr0,
            final REQUEST req) throws InvalidParseOperationException {
        if (command == null) {
            throw new InvalidParseOperationException("Not correctly parsed: " + refCommand);
        }
        final List<TypeRequest> trlist = new ArrayList<>();
        if (command.isArray()) {
            // multiple elements in array
            for (final JsonNode subcommand : command) {
                // one item
                final Entry<String, JsonNode> requestItem = JsonHandler.checkUnicity(refCommand, subcommand);
                final TypeRequest tr = analyzeOneCommand(requestItem.getKey(), requestItem.getValue());
                trlist.add(tr);
                unionTransaction(tr0, tr);
            }
        } else {
            throw new InvalidParseOperationException("Boolean operator needs an array of expression: " + command);
        }
        // MD
        tr0.requestModel = JsonHandler.createObjectNode();
        ArrayNode array = null;
        if (req == REQUEST.not) {
            if (trlist.size() == 1) {
                tr0.requestModel.set(REQUEST.not.exactToken(), trlist.get(0).requestModel);
            } else {
                array = tr0.requestModel.putObject(REQUEST.not.exactToken()).putArray(REQUEST.and.exactToken());
            }
        } else {
            array = tr0.requestModel.putArray(refCommand);
        }
        if (array != null) {
            for (int i = 0; i < trlist.size(); i++) {
                final TypeRequest tr = trlist.get(i);
                if (tr.requestModel != null) {
                    array.add(tr.requestModel);
                }
            }
        }
    }
}