All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.redhat.lightblue.savedsearch.FindRequestBuilder Maven / Gradle / Ivy

The newest version!
/*
 Copyright 2013 Red Hat, Inc. and/or its affiliates.

 This file is part of lightblue.

 This program 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.

 This program 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 this program.  If not, see .
 */
package com.redhat.lightblue.savedsearch;

import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;

import java.io.IOException;

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

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.fasterxml.jackson.databind.node.NullNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;

import com.redhat.lightblue.ClientIdentification;
import com.redhat.lightblue.EntityVersion;

import com.redhat.lightblue.crud.FindRequest;

import com.redhat.lightblue.metadata.TypeResolver;
import com.redhat.lightblue.metadata.Type;
import com.redhat.lightblue.metadata.types.StringType;

import com.redhat.lightblue.query.*;

import com.redhat.lightblue.util.JsonUtils;
import com.redhat.lightblue.util.Error;

/**
 * Builds a find request from a saved search
 */
public class FindRequestBuilder {

    public static final String ERR_SAVED_SEARCH_INVALID_TYPE="crud:saved-search:invalidType";
    public static final String ERR_SAVED_SEARCH_NO_DEFAULT_VALUE="crud:saved-search:noDefaultValue";
    public static final String ERR_SAVED_SEARCH_MISSING_PARAM="crud:saved-search:missing";

    private static final Logger LOGGER = LoggerFactory.getLogger(FindRequestBuilder.class);

    /**
     * Given the parameter values supplied by the caller, returns a
     * map containing default values for missing parameters. If there
     * are missing required parameters, throws an Error with missing
     * parameters.
     */
    public static Map fillDefaults(JsonNode savedSearch,
                                                  Map parameterValues,
                                                  TypeResolver types) {
        Map ret=new HashMap<>();
        JsonNode parametersNode=savedSearch.get("parameters");
        if(parametersNode instanceof ArrayNode) {
            for(Iterator itr=parametersNode.elements();itr.hasNext();) {
                JsonNode parameterNode=itr.next();
                if(parameterNode instanceof ObjectNode) {
                    Type type=null;
                    JsonNode x=parameterNode.get("name");
                    String name=x.asText();
                    x=parameterNode.get("type");
                    if(x!=null) {
                        type=types.getType(x.asText());
                        if(type==null) {
                            throw Error.get(ERR_SAVED_SEARCH_INVALID_TYPE,x.asText());
                        }
                    } else {
                        type=StringType.TYPE;
                    }
                    boolean optional=false;
                    x=parameterNode.get("optional");                    
                    if(x!=null) {
                        optional=x.asBoolean();
                    }
                    if(parameterValues.containsKey(name)) {
                        ret.put(name,(String)StringType.TYPE.cast(type.cast(parameterValues.get(name))));
                    } else if(optional) {
                        // Fill it in using default value                    
                        JsonNode defaultValue=parameterNode.get("defaultValue");
                        if(defaultValue==null)
                            throw Error.get(ERR_SAVED_SEARCH_NO_DEFAULT_VALUE,name);
                        ret.put(name,(String)StringType.TYPE.cast(type.fromJson(defaultValue)));
                    } else {
                        throw Error.get(ERR_SAVED_SEARCH_MISSING_PARAM,name);
                    }                    
                }
            }
        }
        return ret;
    }

    /**
     * Builds a find request from the saved search by rewriting the
     * search bound parameters using parameter values. The search
     * query components can be either strings, or JSON objects. If
     * they are strings, the parameters are replaced first, then the
     * resulting json string is converted to a query/projection. If
     * the components are JSON objects, then the values of those json
     * objects are replaced with parameter values.
     */
    public static FindRequest buildRequest(JsonNode savedSearch,
                                           String entity,
                                           String version,
                                           ClientIdentification clid,
                                           Map parameterValues)
        throws IOException {
        FindRequest request=new FindRequest();
        request.setEntityVersion(new EntityVersion(entity,version));
        request.setClientId(clid);
        JsonNode node=savedSearch.get("query");
        if(node instanceof TextNode) {
            request.setQuery(QueryExpression.fromJson(JsonUtils.json(applyParameters(node.asText(),parameterValues))));
        } else {
            request.setQuery(QueryExpression.fromJson(applyParameters(node,parameterValues)));
        }
        node=savedSearch.get("projection");
        if(node instanceof ArrayNode||
           node instanceof ObjectNode) {
            request.setProjection(Projection.fromJson(applyParameters(node,parameterValues)));
        } else if(node instanceof TextNode) {
            request.setProjection(Projection.fromJson(JsonUtils.json(applyParameters(node.asText(),parameterValues))));
        }
        node=savedSearch.get("sort");
        if(node instanceof ArrayNode||
           node instanceof ObjectNode) {
            request.setSort(Sort.fromJson(applyParameters(node,parameterValues)));
        } else if(node instanceof TextNode) {
            request.setSort(Sort.fromJson(JsonUtils.json(applyParameters(node.asText(),parameterValues))));
        }
        node=savedSearch.get("range");
        if(node instanceof ArrayNode) {
            if(node.size()==2) {
                request.setFrom(node.get(0).asLong());
                request.setTo(node.get(1).asLong());
            }
        }
        return request;
    }

    public static JsonNode applyParameters(JsonNode source,Map parameters) {
        if(source instanceof ObjectNode) {
            return applyParameters( (ObjectNode) source, parameters);
        } else if(source instanceof ArrayNode) {
            return applyParameters( (ArrayNode)source, parameters);
        } else if(source instanceof TextNode) {
            String olds=source.asText();
            String news=applyParameters(olds,parameters);
            if(olds!=news) {
                return JsonNodeFactory.instance.textNode(news);
            } else {
                return source;
            }
        } else {
            return source;
        }
    }

    public static String applyParameters(String source,Map parameters) {
        int n=source.length();
        StringBuilder bld=new StringBuilder(n);
        StringBuilder param=new StringBuilder(32);
        boolean modified=false;
        int state=0;
        for(int i=0;i parameters) {
        ArrayNode newNode=JsonNodeFactory.instance.arrayNode();
        for(Iterator itr=source.elements();itr.hasNext();) {
            newNode.add(applyParameters(itr.next(),parameters));
        }
        return newNode;
    }

    private static JsonNode applyParameters(ObjectNode source,Map parameters) {
        ObjectNode newNode=JsonNodeFactory.instance.objectNode();
        for(Iterator> itr=source.fields();itr.hasNext();) {
            Map.Entry elem=itr.next();
            newNode.set(elem.getKey(),applyParameters(elem.getValue(),parameters));
        }
        return newNode;
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy