Java tutorial
/* * Copyright (c) 2017, Quancheng-ec.com All right reserved. This software is the * confidential and proprietary information of Quancheng-ec.com ("Confidential * Information"). You shall not disclose such Confidential Information and shall * use it only in accordance with the terms of the license agreement you entered * into with Quancheng-ec.com. */ package com.quancheng.saluki.core.grpc.router.internal; import java.text.ParseException; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Maps; import com.quancheng.saluki.core.common.Constants; import com.quancheng.saluki.core.common.GrpcURL; import com.quancheng.saluki.core.common.GrpcURLUtils; import com.quancheng.saluki.core.grpc.router.GrpcRouter; /** * @author shimingliu 201719 ?2:22:04 * @version ConditionRouter.java, v 0.0.1 201719 ?2:22:04 shimingliu */ public class ConditionRouter extends GrpcRouter { private static final Logger log = LoggerFactory.getLogger(ConditionRouter.class); private static final Pattern ROUTE_PATTERN = Pattern.compile("([&!=,]*)\\s*([^&!=,\\s]+)"); private Map<String, MatchPair> whenCondition; private Map<String, MatchPair> thenCondition; public ConditionRouter(String routerMessage) { super(routerMessage); } @Override protected void parseRouter() { whenCondition = Maps.newHashMap(); thenCondition = Maps.newHashMap(); String rulestr = super.getRule(); String[] rules = StringUtils.split(rulestr, "\n"); for (String rule : rules) { int i = rule.trim().indexOf("=>"); String whenRule = i < 0 ? null : rule.substring(0, i).trim(); String thenRule = i < 0 ? rule.trim() : rule.substring(i + 2).trim(); try { whenCondition.putAll(doParseRule(whenRule)); thenCondition.putAll(doParseRule(thenRule)); } catch (ParseException e) { log.error(e.getMessage(), e); } } } @Override public boolean match(List<GrpcURL> providerUrls) { GrpcURL refUrl = super.getRefUrl(); // ?arg???arg? refUrl = refUrl.removeParameter(Constants.ARG_KEY); if (matchWhen(refUrl)) { boolean allMatchThen = false; for (GrpcURL providerUrl : providerUrls) { if (matchThen(refUrl, providerUrl)) { allMatchThen = true; } else { allMatchThen = false; break; } } if (allMatchThen) { return true; } else { return false; } } else { return true; } } private boolean matchWhen(GrpcURL refUrl) { return matchCondition(whenCondition, refUrl, null); } private boolean matchThen(GrpcURL refUrl, GrpcURL providerUrl) { return thenCondition != null && matchCondition(thenCondition, refUrl, providerUrl); } private boolean matchCondition(Map<String, MatchPair> condition, GrpcURL url, GrpcURL param) { Map<String, String> sample = url.toMap(); for (Map.Entry<String, String> entry : sample.entrySet()) { String key = entry.getKey(); MatchPair pair = condition.get(key); if (pair != null && !pair.isMatch(entry.getValue(), param)) { return false; } } return true; } // help method private final class MatchPair { final Set<String> matches = new HashSet<String>(); final Set<String> mismatches = new HashSet<String>(); public boolean isMatch(String value, GrpcURL param) { for (String match : matches) { if (!GrpcURLUtils.isMatchGlobPattern(match, value, param)) { return false; } } for (String mismatch : mismatches) { if (GrpcURLUtils.isMatchGlobPattern(mismatch, value, param)) { return false; } } return true; } } private Map<String, MatchPair> doParseRule(String rule) throws ParseException { Map<String, MatchPair> condition = new HashMap<String, MatchPair>(); if (StringUtils.isBlank(rule)) { return condition; } // ???Key-Value MatchPair pair = null; // Value Set<String> values = null; final Matcher matcher = ROUTE_PATTERN.matcher(rule); while (matcher.find()) { // ?? String separator = matcher.group(1); String content = matcher.group(2); // ? if (separator == null || separator.length() == 0) { pair = new MatchPair(); condition.put(content, pair); } // KV else if ("&".equals(separator)) { if (condition.get(content) == null) { pair = new MatchPair(); condition.put(content, pair); } else { condition.put(content, pair); } } // KVValue else if ("=".equals(separator)) { if (pair == null) throw new ParseException("Illegal route rule \"" + rule + "\", The error char '" + separator + "' at index " + matcher.start() + " before \"" + content + "\".", matcher.start()); values = pair.matches; values.add(content); } // KVValue else if ("!=".equals(separator)) { if (pair == null) throw new ParseException("Illegal route rule \"" + rule + "\", The error char '" + separator + "' at index " + matcher.start() + " before \"" + content + "\".", matcher.start()); values = pair.mismatches; values.add(content); } // KVValue? else if (",".equals(separator)) { // ? if (values == null || values.size() == 0) throw new ParseException("Illegal route rule \"" + rule + "\", The error char '" + separator + "' at index " + matcher.start() + " before \"" + content + "\".", matcher.start()); values.add(content); } else { throw new ParseException("Illegal route rule \"" + rule + "\", The error char '" + separator + "' at index " + matcher.start() + " before \"" + content + "\".", matcher.start()); } } return condition; } }