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

io.shardingjdbc.core.util.InlineExpressionParser Maven / Gradle / Ivy

There is a newer version: 2.0.3
Show newest version
/*
 * Copyright 1999-2015 dangdang.com.
 * 

* 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 io.shardingjdbc.core.util; import com.google.common.base.Function; import com.google.common.collect.Collections2; import com.google.common.collect.Sets; import groovy.lang.GString; import groovy.lang.GroovyShell; import lombok.RequiredArgsConstructor; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; /** * Inline expression parser. * * @author gaohongtao * @author zhangliang */ @RequiredArgsConstructor public final class InlineExpressionParser { private static final char SPLITTER = ','; private final String inlineExpression; /** * Split and evaluate inline expression. * * @return result list */ public List evaluate() { if (null == inlineExpression) { return Collections.emptyList(); } return flatten(evaluate(split())); } private List evaluate(final List inlineExpressions) { List result = new ArrayList<>(inlineExpressions.size()); GroovyShell shell = new GroovyShell(); for (String each : inlineExpressions) { StringBuilder expression = new StringBuilder(each); if (!each.startsWith("\"")) { expression.insert(0, "\""); } if (!each.endsWith("\"")) { expression.append("\""); } result.add(shell.evaluate(expression.toString())); } return result; } private List split() { List result = new ArrayList<>(); StringBuilder segment = new StringBuilder(); int bracketsDepth = 0; for (int i = 0; i < inlineExpression.length(); i++) { char each = inlineExpression.charAt(i); switch (each) { case SPLITTER: if (bracketsDepth > 0) { segment.append(each); } else { result.add(segment.toString().trim()); segment.setLength(0); } break; case '$': if ('{' == inlineExpression.charAt(i + 1)) { bracketsDepth++; } segment.append(each); break; case '}': if (bracketsDepth > 0) { bracketsDepth--; } segment.append(each); break; default: segment.append(each); break; } } if (segment.length() > 0) { result.add(segment.toString().trim()); } return result; } private List flatten(final List segments) { List result = new ArrayList<>(); for (Object each : segments) { if (each instanceof GString) { result.addAll(assemblyCartesianSegments((GString) each)); } else { result.add(each.toString()); } } return result; } private List assemblyCartesianSegments(final GString segment) { Set> cartesianValues = getCartesianValues(segment); List result = new ArrayList<>(cartesianValues.size()); for (List each : cartesianValues) { result.add(assemblySegment(each, segment)); } return result; } @SuppressWarnings("unchecked") private Set> getCartesianValues(final GString segment) { List> result = new ArrayList<>(segment.getValues().length); for (Object each : segment.getValues()) { if (null == each) { continue; } if (each instanceof Collection) { result.add(Sets.newLinkedHashSet(Collections2.transform((Collection) each, new Function() { @Override public String apply(final Object input) { return input.toString(); } }))); } else { result.add(Sets.newHashSet(each.toString())); } } return Sets.cartesianProduct(result); } private String assemblySegment(final List cartesianValue, final GString segment) { StringBuilder result = new StringBuilder(); for (int i = 0; i < segment.getStrings().length; i++) { result.append(segment.getStrings()[i]); if (i < cartesianValue.size()) { result.append(cartesianValue.get(i)); } } return result.toString(); } }