com.mingo.query.util.QueryUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.mingo.query.util.QueryUtils.java

Source

package com.mingo.query.util;

import static org.slf4j.helpers.MessageFormatter.format;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.mingo.query.Query;
import com.mingo.query.QuerySet;
import com.mongodb.util.JSON;
import com.mongodb.util.JSONParseException;
import com.mongodb.util.JSONSerializers;
import com.mongodb.util.ObjectSerializer;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Copyright 2012-2013 The Mingo Team
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public final class QueryUtils {

    private QueryUtils() {
    }

    private static final int DB_NAME_POSITION = 0;
    private static final int COLLECTION_NAME_POSITION = 1;
    private static final int QUERY_ID_POSITION = 2;
    private static final int NUMBER_OF_ELEMENTS = 3;

    /* this prefixed must be placed before parameter name */
    private static final String PARAMETER_PREFIX = "#";
    private static final String PARAMETER_PATTERN = "\"" + PARAMETER_PREFIX + "{}\"";
    private static final String PIPELINE_TEMPLATE = "[{}]";
    private static final ObjectSerializer OBJECT_SERIALIZER = JSONSerializers.getLegacy();

    /**
     * Builds composite query ID ith next structure "dbName.collectionName.id".
     *
     * @param dbName         DB name
     * @param collectionName collection name
     * @param id             query id
     * @return composite ID - { [dbName].[collectionName].[id] }
     */
    public static String buildCompositeId(String dbName, String collectionName, String id) {
        Validate.notBlank(dbName, "dbName cannot be null");
        Validate.notBlank(collectionName, "collectionName cannot be null");
        Validate.notBlank(id, "id cannot be null");
        return StringUtils.join(Lists.newArrayList(dbName, collectionName, id), ".");
    }

    /**
     * Gets db name from composite query id.
     *
     * @param compositeQueryId composite query id
     * @return db name
     */
    public static String getDbName(String compositeQueryId) {
        String[] elements = StringUtils.split(compositeQueryId, ".");
        return getElementByPosition(elements, NUMBER_OF_ELEMENTS, DB_NAME_POSITION);
    }

    /**
     * Gets collection name from composite query id.
     *
     * @param compositeQueryId composite query id
     * @return collection name
     */
    public static String getCollectionName(String compositeQueryId) {
        String[] elements = StringUtils.split(compositeQueryId, ".");
        return getElementByPosition(elements, NUMBER_OF_ELEMENTS, COLLECTION_NAME_POSITION);
    }

    /**
     * Gets query id from composite query id.
     *
     * @param compositeQueryId composite query id
     * @return query id
     */
    public static String getQueryId(String compositeQueryId) {
        String[] elements = getCompositeIdElements(compositeQueryId);
        return getElementByPosition(elements, NUMBER_OF_ELEMENTS, QUERY_ID_POSITION);
    }

    /**
     * Gets elements of  composite query id.
     *
     * @param compositeQueryId composite query id
     * @return elements of  composite query id
     */
    public static String[] getCompositeIdElements(String compositeQueryId) {
        return StringUtils.split(compositeQueryId, ".");
    }

    /**
     * Creates composite Id for all queries in querySet.
     *
     * @param querySet {@link com.mingo.query.QuerySet}
     */
    public static void createCompositeIdForQueries(QuerySet querySet) {
        if (MapUtils.isEmpty(querySet.getQueries())) {
            return;
        }
        for (Query query : querySet.getQueries().values()) {
            query.setCompositeId(
                    buildCompositeId(querySet.getDbName(), querySet.getCollectionName(), query.getId()));
        }
    }

    /**
     * Validates composite id.
     *
     * @param compositeId expected format ( [database-name].[collection-name].[query-id] )
     * @throws NullPointerException     {@link NullPointerException}
     * @throws IllegalArgumentException {@link IllegalArgumentException}
     *                                  if composite id is null, empty, contains only spaces or has wrong format.
     */
    public static void validateCompositeId(String compositeId)
            throws NullPointerException, IllegalArgumentException {
        Validate.notBlank(compositeId, "compositeId cannot be null or empty");
        String[] elements = StringUtils.split(compositeId, ".");
        Validate.isTrue(elements.length == NUMBER_OF_ELEMENTS, "composite id should consist of three parts: "
                + "([database-name].[collection-name].[query-id]). current value: " + compositeId);
        for (int index = 0; index < elements.length; index++) {
            Validate.notBlank(elements[index], "element with position: " + (index + 1)
                    + " in composite id is empty. current value: " + compositeId);
        }
    }

    private static String getElementByPosition(String[] elements, int numberOfElements, int pos) {
        if (elements != null && elements.length == numberOfElements && pos < numberOfElements) {
            return elements[pos];
        } else {
            return null;
        }
    }

    /**
     * Checks what query has valid format.
     *
     * @param query query
     * @return true if query is correct otherwise - false
     */
    public static boolean validate(String query) {
        boolean valid = true;
        try {
            JSON.parse(query);
        } catch (JSONParseException e) {
            valid = false;
        }
        return valid;
    }

    /**
     * Wraps query in [] brackets.
     *
     * @param query query
     * @return wrapped query
     */
    public static String wrap(String query) {
        return format(PIPELINE_TEMPLATE, query).getMessage();
    }

    /**
     * Replace parameters in query.
     *
     * @param query      query
     * @param parameters parameters
     * @return prepared query
     */
    public static String replaceQueryParameters(String query, Map<String, Object> parameters) {
        if (StringUtils.isNotBlank(query) && MapUtils.isNotEmpty(parameters)) {
            for (Map.Entry<String, Object> parameter : parameters.entrySet()) {
                if (StringUtils.isNotEmpty(parameter.getKey())) {
                    if (isParameterEmpty(parameter.getValue())) {
                        query = StringUtils.replace(query, PARAMETER_PREFIX + parameter.getKey(),
                                StringUtils.EMPTY);
                    } else {
                        String replacement = createReplacement(parameter.getKey(), parameter.getValue());
                        query = StringUtils.replace(query, replacement, getParameterAsString(parameter.getValue()));
                    }
                }
            }
        }
        return removeParameters(query);
    }

    private static String removeParameters(String query) {
        if (StringUtils.isBlank(query)) {
            return query;
        }
        int paramPrefixIndex = query.indexOf(PARAMETER_PREFIX);
        if (paramPrefixIndex > 0) {
            return removeParameters(
                    query.replace(getParameterPlaceholder(paramPrefixIndex, query), StringUtils.EMPTY));

        }
        return query;
    }

    private static String getParameterPlaceholder(int paramPrefixIndex, String query) {
        for (int i = paramPrefixIndex; i < query.length(); i++) {
            if ("\"".equals(String.valueOf(query.charAt(i)))) {
                return query.substring(paramPrefixIndex, i);
            }
        }
        return StringUtils.EMPTY;
    }

    private static String getParameterAsString(Object parameter) {
        if (isParameterEmpty(parameter)) {
            return StringUtils.EMPTY;
        }
        String val;
        if (isTypeSupported(parameter)) {
            if (parameter instanceof Collection) {
                val = toString((Collection) parameter);
            } else if (parameter instanceof Object[]) {
                val = toString((Object[]) parameter);
            } else if (parameter instanceof Date) {
                val = OBJECT_SERIALIZER.serialize(parameter);
            } else {
                val = parameter.toString();
            }
        } else {
            throw new RuntimeException("unsupported parameter type. parameter value: " + parameter + ", class: "
                    + parameter.getClass());
        }
        return val;
    }

    private static String toString(Object[] array) {
        return toString(Lists.newArrayList(array));
    }

    private static String toString(Collection<?> collection) {
        List<String> values = Lists.transform(Lists.newArrayList(collection), new Function<Object, String>() {
            @Override
            public String apply(Object input) {
                return "'" + input.toString() + "'";
            }
        });
        return "[" + StringUtils.join(values, ",") + "]";
    }

    private static boolean isParameterEmpty(Object val) {
        return !(isParameterNotEmpty(val));
    }

    private static boolean isParameterNotEmpty(Object val) {
        if (val == null) {
            return false;
        }
        if (val instanceof Collection) {
            return !((Collection) val).isEmpty();
        } else if (val instanceof Object[]) {
            return ((Object[]) val).length > 0;
        } else if (val instanceof String) {
            return StringUtils.isNotEmpty((String) val);
        }
        return true;
    }

    private static String createReplacement(String name, Object value) {
        return (isFullReplace(value)) ? format(PARAMETER_PATTERN, name).getMessage() : PARAMETER_PREFIX + name;
    }

    private static boolean isFullReplace(Object parameter) {
        return parameter instanceof Collection || parameter instanceof Object[] || parameter instanceof Number
                || parameter instanceof Date;
    }

    private static boolean isTypeSupported(Object val) {
        return val instanceof String || val instanceof Number || val instanceof Date || val instanceof Collection
                || val instanceof Object[] || val instanceof Enum;
    }

}