com.addthis.hydra.data.query.Query.java Source code

Java tutorial

Introduction

Here is the source code for com.addthis.hydra.data.query.Query.java

Source

/*
 * 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
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */
package com.addthis.hydra.data.query;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

import com.addthis.basis.util.CUID;
import com.addthis.basis.util.LessStrings;

import com.addthis.bundle.channel.DataChannelOutput;
import com.addthis.codec.codables.Codable;
import com.addthis.codec.json.CodecJSON;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

import org.apache.commons.lang3.mutable.MutableInt;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.channel.ChannelProgressivePromise;

/**
 * Object representation of a tree query.
 */
@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public class Query implements Codable {

    public static final Logger traceLog = LoggerFactory.getLogger("query-trace");

    private static final int MAX_PRINT_LENGTH = 3000;
    private static final String SESSION_ID = CUID.createCUID();

    private static final AtomicLong queryIds = new AtomicLong(0);

    @JsonProperty
    private String[] paths;
    @JsonProperty
    private String[] ops;
    @JsonProperty
    private String job;
    @JsonProperty
    private boolean trace;
    @JsonProperty
    private String sessionId;
    @JsonProperty
    private long queryId;
    @JsonProperty
    private HashMap<String, String> params = new HashMap<>();

    @JsonIgnore
    public transient ChannelProgressivePromise queryPromise = null;

    private Query() {
    }

    public Query(String job, String[] paths, String[] ops) {
        this.job = job;
        this.paths = paths;
        this.ops = ops;
        this.sessionId = SESSION_ID;
        this.queryId = queryIds.incrementAndGet();
    }

    public ChannelProgressivePromise getQueryPromise() {
        return queryPromise;
    }

    public static String getPathString(QueryElement... path) {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        for (QueryElement e : path) {
            if (i++ > 0) {
                sb.append("/");
            }
            e.toCompact(sb);
        }
        return sb.toString();
    }

    public static String getShortPathString(QueryElement... path) {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        for (QueryElement e : path) {
            if (i++ > 0) {
                sb.append("/");
            }
            e.toCompact(sb);
        }
        String queryString = sb.toString();
        if (queryString.length() > MAX_PRINT_LENGTH) {
            queryString = queryString.substring(0, MAX_PRINT_LENGTH);
        }
        return queryString;
    }

    public String uuid() {
        return String.valueOf(queryId);
    }

    public long queryId() {
        return queryId;
    }

    public String sessionId() {
        return sessionId;
    }

    @Override
    public String toString() {
        try {
            String queryString = CodecJSON.encodeString(this);
            if (queryString != null && queryString.length() > MAX_PRINT_LENGTH) {
                queryString = queryString.substring(0, MAX_PRINT_LENGTH);
            }
            return queryString;
        } catch (Exception ex) {
            return LessStrings.join(paths, "|").concat(";").concat(ops != null ? LessStrings.join(ops, "|") : "")
                    .concat(";").concat(job != null ? job : "");
        }
    }

    public String[] getPaths() {
        return paths;
    }

    public boolean isTraced() {
        return trace;
    }

    public Query setTraced(boolean traced) {
        this.trace = traced;
        return this;
    }

    public List<QueryElement[]> getQueryPaths() {
        ArrayList<QueryElement[]> list = new ArrayList<>(paths.length);
        for (String path : paths) {
            list.add(parseQueryPath(path));
        }
        return list;
    }

    /**
     * turns compact query notation (+:+hits) into an object array
     */
    private static QueryElement[] parseQueryPath(String path) {
        MutableInt column = new MutableInt(0);
        ArrayList<QueryElement> list = new ArrayList<>();
        for (String pe : LessStrings.split(path, "/")) {
            list.add(new QueryElement().parse(pe, column));
        }
        return list.toArray(new QueryElement[list.size()]);
    }

    public QueryOpProcessor newProcessor(DataChannelOutput output, ChannelProgressivePromise opPromise) {
        return new QueryOpProcessor(output, ops, opPromise);
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public String[] getOps() {
        return ops;
    }

    /**
     * @return first a query suitable for the next query worker in the stack
     */
    public Query createPipelinedQuery() {
        Query newQuery = cloneTo(new Query());
        if (ops != null && ops.length > 0) {
            String[] newops = new String[ops.length - 1];
            System.arraycopy(ops, 1, newops, 0, newops.length);
            newQuery.ops = newops;
            String pop = ops[0];
            ops = new String[] { pop };
        }
        return newQuery;
    }

    private Query cloneTo(Query q) {
        q.paths = paths;
        q.ops = ops;
        q.job = job;
        q.trace = trace;
        q.params = params;
        q.sessionId = sessionId;
        q.queryId = queryId;
        return q;
    }

    public HashMap<String, String> getParameters() {
        return params;
    }

    public Query setParameterIfNotYetSet(String key, Object value) {
        if (params.get(key) == null) {
            setParameter(key, value);
        }
        return this;
    }

    public Query setParameter(String key, Object value) {
        if (value != null) {
            params.put(key, value.toString());
        } else {
            params.remove(key);
        }
        return this;
    }

    public String getParameter(String key) {
        return getParameter(key, null);
    }

    public String getParameter(String key, String defaultValue) {
        String val = params.get(key);
        return val != null ? val : defaultValue;
    }

    public String removeParameter(String key) {
        return params.remove(key);
    }
}