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

com.cisco.oss.foundation.directory.query.QueryCriterionParser Maven / Gradle / Ivy

There is a newer version: 1.2.1-5
Show newest version
/**
 * Copyright 2014 Cisco Systems, Inc.
 *
 * 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.cisco.oss.foundation.directory.query;

import java.util.ArrayList;
import java.util.List;

import com.cisco.oss.foundation.directory.query.ServiceInstanceQuery.ContainQueryCriterion;
import com.cisco.oss.foundation.directory.query.ServiceInstanceQuery.EqualQueryCriterion;
import com.cisco.oss.foundation.directory.query.ServiceInstanceQuery.InQueryCriterion;
import com.cisco.oss.foundation.directory.query.ServiceInstanceQuery.NotContainQueryCriterion;
import com.cisco.oss.foundation.directory.query.ServiceInstanceQuery.NotEqualQueryCriterion;
import com.cisco.oss.foundation.directory.query.ServiceInstanceQuery.NotInQueryCriterion;
import com.cisco.oss.foundation.directory.query.ServiceInstanceQuery.PatternQueryCriterion;

/**
 * It is a Parser to convert QueryCriterion from/to commandline expression string
 *
 */
public class QueryCriterionParser {

    /**
     * Convert the QueryCriterion to a String expression.
     *
     * @param queryCriterion
     *         the QueryCriterion.
     * @return
     *         the String expression.
     */
    private static String criterionToExpressionStr(QueryCriterion queryCriterion){
        if(queryCriterion instanceof EqualQueryCriterion){
            EqualQueryCriterion criterion = (EqualQueryCriterion) queryCriterion;
            return criterion.getMetadataKey() + " equals " + escapeString(criterion.getCriterion());
        } else if(queryCriterion instanceof NotEqualQueryCriterion){
            NotEqualQueryCriterion criterion = (NotEqualQueryCriterion) queryCriterion;
            return criterion.getMetadataKey() + " not equals " + escapeString(criterion.getCriterion());
        } else if(queryCriterion instanceof ContainQueryCriterion){
            ContainQueryCriterion criterion = (ContainQueryCriterion) queryCriterion;
            return criterion.getMetadataKey();
        } else if(queryCriterion instanceof NotContainQueryCriterion){
            NotContainQueryCriterion criterion = (NotContainQueryCriterion) queryCriterion;
            return "not " + criterion.getMetadataKey();
        } else if(queryCriterion instanceof InQueryCriterion){
            InQueryCriterion criterion = (InQueryCriterion) queryCriterion;
            StringBuilder sb = new StringBuilder(criterion.getMetadataKey());
            sb.append(" in [ ");
            for(String s : criterion.getCriterion()){
                sb.append(escapeString(s)).append(", ");
            }
            sb.append("]");
            return sb.toString();
        } else if(queryCriterion instanceof NotInQueryCriterion){
            NotInQueryCriterion criterion = (NotInQueryCriterion) queryCriterion;
            StringBuilder sb = new StringBuilder(criterion.getMetadataKey());
            sb.append(" not in [ ");
            for(String s : criterion.getCriterion()){
                sb.append(escapeString(s)).append(", ");
            }
            sb.append("]");
            return sb.toString();
        } else if(queryCriterion instanceof PatternQueryCriterion){
            PatternQueryCriterion criterion = (PatternQueryCriterion) queryCriterion;
            return criterion.getMetadataKey() + " matches " + escapeString(criterion.getCriterion());
        }
        return "";
    }

    /**
     * Parse from statement String expression to QueryCriterion.
     *
     * @param statement
     *         the statement String expression.
     * @return
     *         the QueryCriterion.
     */
    public static QueryCriterion toQueryCriterion(String statement){
        char [] delimiter = {' ', '\t', ',', '[', ']'};
        List cmdList = splitStringByDelimiters(statement, delimiter, true);
        List tokenList = filterDelimiterElement(cmdList, delimiter);
        if(tokenList.size() == 1){
            String key = cmdList.get(0);
            if(! key.isEmpty()){
                return new ContainQueryCriterion(key);
            }
        } else if(tokenList.size() == 2){
            String cmd = cmdList.get(0);
            String key = cmdList.get(1);
            if(! key.isEmpty() && cmd.equals("not")){
                return new NotContainQueryCriterion(key);
            }
        } else {
            String key = tokenList.get(0);
            String op = tokenList.get(1);
            if(op.equals("not")){
                op = op + " " + tokenList.get(2);
            }

            if(op.equals("equals")){
                String value = unescapeString(tokenList.get(2));
                if(value != null){
                    return new EqualQueryCriterion(key, value);
                }
            } else if(op.equals("not equals")){
                String value = unescapeString(tokenList.get(3));
                if(value != null){
                    return new NotEqualQueryCriterion(key, value);
                }
            } else if(op.equals("matches")){
                String value = unescapeString(tokenList.get(2));
                if(value != null){
                    return new PatternQueryCriterion(key, value);
                }
            } else if(op.equals("in")){
                List values = new ArrayList();
                boolean start = false;
                for(String s : cmdList){
                    if(s.isEmpty() || s.equals(",")){
                        continue;
                    } else if(s.equals("[")){
                        start = true;
                        continue;
                    } else if(s.equals("]")){
                        start = false;
                        break;
                    } else if(start){
                        String v = unescapeString(s);
                        if(v != null){
                            values.add(v);
                        }
                    }
                }
                return new InQueryCriterion(key, values);
            } else if(op.equals("not in")){
                List values = new ArrayList();
                boolean start = false;
                for(String s : cmdList){
                    if(s.isEmpty() || s.equals(",")){
                        break;
                    } else if(s.equals("[")){
                        start = true;
                        continue;
                    } else if(s.equals("]")){
                        start = false;
                        break;
                    } else if(start){
                        String v = unescapeString(s);
                        if(v != null){
                            values.add(v);
                        }

                    }
                }
                return new NotInQueryCriterion(key, values);
            }
        }
        return null;
    }

    /**
     * Parse the ServiceInstanceQuery from commandline String expression.
     *
     * Convert the ServiceInstanceQuery commandline input to the ServiceInstanceQuery.
     *
     * @param cli
     *         the ServiceInstanceQuery commandline String expression.
     * @return
     *         the QueryCriterion statement String list.
     */
    public static ServiceInstanceQuery toServiceInstanceQuery(String cli){
        char [] delimiters = {';'};
        ServiceInstanceQuery query = new ServiceInstanceQuery();
        for(String statement : splitStringByDelimiters(cli, delimiters, false)){
            QueryCriterion criterion = toQueryCriterion(statement);
            if(criterion != null){
                query.addQueryCriterion(criterion);
            }
        };
        return query;
    }

    /**
     * Convert the ServiceInstanceQuery to the commandline string expression.
     *
     * @param query
     *         the ServiceInstanceQuery.
     * @return
     *         the string expression.
     */
    public static String queryToExpressionStr(ServiceInstanceQuery query){
        List criteria = query.getCriteria();
        StringBuilder sb = new StringBuilder();
        for(QueryCriterion criterion : criteria){
            String statement = criterionToExpressionStr(criterion);
            if(statement != null && ! statement.isEmpty()){
                sb.append(statement).append(";");
            }
        }
        return sb.toString();
    }

    /**
     * Escape the String for the QueryCriterion String.
     *
     * Add " to the head and tail, switch " to \".
     *
     * @param str
     *         the origin String.
     * @return
     *         the escaped String
     */
    private static String escapeString(String str){
        return "\"" +  str.replaceAll("\"", "\\\\\"") + "\"";
    }

    /**
     * Unescape the QueryCriterion String.
     *
     * remove the head and tail ", switch \" to ".
     *
     * @param str
     *         the escaped String.
     * @return
     *         the origin String.
     */
    private static String unescapeString(String str){
        if(str.startsWith("\"") && str.endsWith("\"")){
            String s = str.replaceAll("\\\\\"", "\"");
            return s.substring(1, s.length() -1);
        }
        return null;
    }

    /**
     * Filter the delimiter from the String array.
     *
     * remove the String element in the delimiter.
     *
     * @param arr
     *         the target array.
     * @param delimiters
     *         the delimiter array need to remove.
     * @return
     *         the array List.
     */
    private static List filterDelimiterElement(List arr, char[] delimiters){
        List list = new ArrayList();
        for(String s : arr){
            if(s == null || s.isEmpty()){
                continue;
            }
            if(s.length() > 1){
                list.add(s);
                continue;
            }
            char strChar = s.charAt(0);
            boolean find = false;
            for(char c : delimiters){
                if(c == strChar){
                    find = true;
                    break;
                }
            }
            if(find == false){
                list.add(s);
            }
        }
        return list;
    }

    /**
     * Split a complete String to String array by the delimeter array.
     *
     * This method is used to split a command or a statement to sub elements.
     * It will trim the sub elements too.
     *
     * @param str
     *         the complete string.
     * @param delimiters
     *         the delimiter array.
     * @param includeDeli
     *         if true, include the delimiter in the return array.
     * @return
     *         the split String array.
     */
    private static List splitStringByDelimiters(String str, char[] delimiters, boolean includeDeli){
        List arr = new ArrayList();
        int i = 0, start = 0, quota = 0;
        char pre = 0;
        for(char c : str.toCharArray()){
            if(c == '"' && pre != '\\'){
                quota ++;
            }
            if(quota % 2 == 0){
                for(char deli : delimiters){
                    if( c == deli){
                        if(includeDeli){
                            arr.add(str.substring(start, i).trim());
                            start = i;
                        }else if(i > start ){
                            arr.add(str.substring(start, i).trim());
                            start = i + 1;
                        }

                    }
                }

            }
            i ++;
            pre = c;
        }

        if(includeDeli){
            arr.add(str.substring(start, i).trim());
            start = i;
        }else if(i > start ){
            arr.add(str.substring(start, i).trim());
        }

        return arr;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy