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

com.alibaba.nacos.naming.selector.interpreter.ExpressionInterpreter Maven / Gradle / Ivy

There is a newer version: 2.4.2
Show newest version
/*
 *  Copyright 1999-2021 Alibaba Group Holding Ltd.
 *
 *  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.alibaba.nacos.naming.selector.interpreter;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.common.utils.StringUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Expression interpreter for label selector.
 *
 * 

For now it supports very limited set of syntax rules. * * @author nokrange */ public class ExpressionInterpreter { private static final Set SUPPORTED_INNER_CONNCETORS = new HashSet<>(); private static final Set SUPPORTED_OUTER_CONNCETORS = new HashSet<>(); private static final String CONSUMER_PREFIX = "CONSUMER.label."; private static final String PROVIDER_PREFIX = "PROVIDER.label."; private static final char CEQUAL = '='; private static final char CAND = '&'; static { SUPPORTED_INNER_CONNCETORS.add(String.valueOf(CEQUAL)); SUPPORTED_OUTER_CONNCETORS.add(String.valueOf(CAND)); } /** * Parse the label expression. * *

Currently we support the very single type of expression: *

     *     consumer.labelA = provider.labelA & consumer.labelB = provider.labelB
     * 
* Later we will implement a interpreter to parse this expression in a standard LL parser way. * * @param expression the label expression to parse * @return collection of labels */ public static Set parseExpression(String expression) throws NacosException { if (StringUtils.isBlank(expression)) { return new HashSet<>(); } expression = StringUtils.deleteWhitespace(expression); List elements = getTerms(expression); Set gotLabels = new HashSet<>(); int index = 0; index = checkInnerSyntax(elements, index); if (index == -1) { throw new NacosException(NacosException.INVALID_PARAM, "parse expression failed!"); } gotLabels.add(elements.get(index++).split(PROVIDER_PREFIX)[1]); while (index < elements.size()) { index = checkOuterSyntax(elements, index); if (index >= elements.size()) { return gotLabels; } if (index == -1) { throw new NacosException(NacosException.INVALID_PARAM, "parse expression failed!"); } gotLabels.add(elements.get(index++).split(PROVIDER_PREFIX)[1]); } return gotLabels; } public static List getTerms(String expression) { List terms = new ArrayList<>(); Set characters = new HashSet<>(); characters.add(CEQUAL); characters.add(CAND); char[] chars = expression.toCharArray(); int lastIndex = 0; for (int index = 0; index < chars.length; index++) { char ch = chars[index]; if (characters.contains(ch)) { terms.add(expression.substring(lastIndex, index)); terms.add(expression.substring(index, index + 1)); index++; lastIndex = index; } } terms.add(expression.substring(lastIndex, chars.length)); return terms; } private static int skipEmpty(List elements, int start) { while (start < elements.size() && StringUtils.isBlank(elements.get(start))) { start++; } return start; } private static int checkOuterSyntax(List elements, int start) { int index = start; index = skipEmpty(elements, index); if (index >= elements.size()) { return index; } if (!SUPPORTED_OUTER_CONNCETORS.contains(elements.get(index++))) { return -1; } return checkInnerSyntax(elements, index); } private static int checkInnerSyntax(List elements, int start) { int index = start; index = skipEmpty(elements, index); if (index >= elements.size()) { return -1; } if (!elements.get(index).startsWith(CONSUMER_PREFIX)) { return -1; } final String labelConsumer = elements.get(index++).split(CONSUMER_PREFIX)[1]; index = skipEmpty(elements, index); if (index >= elements.size()) { return -1; } if (!SUPPORTED_INNER_CONNCETORS.contains(elements.get(index++))) { return -1; } index = skipEmpty(elements, index); if (index >= elements.size()) { return -1; } if (!elements.get(index).startsWith(PROVIDER_PREFIX)) { return -1; } final String labelProvider = elements.get(index).split(PROVIDER_PREFIX)[1]; if (!labelConsumer.equals(labelProvider)) { return -1; } return index; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy