[fix-11295] remove duplicate classes (#11355)
This commit is contained in:
parent
e9ccaffbe0
commit
05932bcf55
|
|
@ -18,21 +18,17 @@
|
|||
package org.apache.dolphinscheduler.common.utils;
|
||||
|
||||
import org.apache.dolphinscheduler.common.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.CommandType;
|
||||
import org.apache.dolphinscheduler.common.utils.placeholder.BusinessTimeUtils;
|
||||
import org.apache.dolphinscheduler.common.utils.placeholder.PlaceholderUtils;
|
||||
import org.apache.dolphinscheduler.common.utils.placeholder.TimePlaceholderUtils;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.model.Property;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parser.PlaceholderUtils;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parser.TimePlaceholderUtils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
|
@ -113,7 +109,6 @@ public class ParameterUtils {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
StringBuffer newValue = new StringBuffer(templateStr.length());
|
||||
|
||||
Matcher matcher = DATE_PARSE_PATTERN.matcher(templateStr);
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.common.utils.placeholder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* placeholder utils
|
||||
*/
|
||||
public class PlaceholderUtils {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PlaceholderUtils.class);
|
||||
|
||||
/**
|
||||
* Prefix of the position to be replaced
|
||||
*/
|
||||
public static final String PLACEHOLDER_PREFIX = "${";
|
||||
|
||||
/**
|
||||
* The suffix of the position to be replaced
|
||||
*/
|
||||
|
||||
public static final String PLACEHOLDER_SUFFIX = "}";
|
||||
|
||||
/**
|
||||
* Replaces all placeholders of format {@code ${name}} with the value returned
|
||||
* from the supplied {@link PropertyPlaceholderHelper.PlaceholderResolver}.
|
||||
*
|
||||
* @param value the value containing the placeholders to be replaced
|
||||
* @param paramsMap placeholder data dictionary
|
||||
* @param ignoreUnresolvablePlaceholders ignoreUnresolvablePlaceholders
|
||||
* @return the supplied value with placeholders replaced inline
|
||||
*/
|
||||
public static String replacePlaceholders(String value,
|
||||
Map<String, String> paramsMap,
|
||||
boolean ignoreUnresolvablePlaceholders) {
|
||||
//replacement tool, parameter key will be replaced by value,if can't match , will throw an exception
|
||||
PropertyPlaceholderHelper strictHelper = getPropertyPlaceholderHelper(false);
|
||||
|
||||
//Non-strict replacement tool implementation, when the position to be replaced does not get the corresponding value, the current position is ignored, and the next position is replaced.
|
||||
PropertyPlaceholderHelper nonStrictHelper = getPropertyPlaceholderHelper(true);
|
||||
|
||||
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
|
||||
|
||||
//the PlaceholderResolver to use for replacement
|
||||
return helper.replacePlaceholders(value, new PropertyPlaceholderResolver(value, paramsMap));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
|
||||
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
|
||||
* be ignored ({@code true}) or cause an exception ({@code false})
|
||||
* @return PropertyPlaceholderHelper
|
||||
*/
|
||||
public static PropertyPlaceholderHelper getPropertyPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
|
||||
|
||||
return new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, null, ignoreUnresolvablePlaceholders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder replacement resolver
|
||||
*/
|
||||
private static class PropertyPlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver {
|
||||
|
||||
private final String value;
|
||||
|
||||
private final Map<String, String> paramsMap;
|
||||
|
||||
public PropertyPlaceholderResolver(String value, Map<String, String> paramsMap) {
|
||||
this.value = value;
|
||||
this.paramsMap = paramsMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
try {
|
||||
return paramsMap.get(placeholderName);
|
||||
} catch (Exception ex) {
|
||||
logger.error("resolve placeholder '{}' in [ {} ]", placeholderName, value, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.common.utils.placeholder;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Utility class for working with Strings that have placeholder values in them. A placeholder takes the form
|
||||
* {@code ${name}}. Using {@code PropertyPlaceholderHelper} these placeholders can be substituted for
|
||||
* user-supplied values. <p> Values for substitution can be supplied using a {@link Properties} instance or
|
||||
* using a {@link PlaceholderResolver}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @since 3.0
|
||||
*/
|
||||
public class PropertyPlaceholderHelper {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(PropertyPlaceholderHelper.class);
|
||||
|
||||
private static final Map<String, String> wellKnownSimplePrefixes = new HashMap<>(4);
|
||||
|
||||
static {
|
||||
wellKnownSimplePrefixes.put("}", "{");
|
||||
wellKnownSimplePrefixes.put("]", "[");
|
||||
wellKnownSimplePrefixes.put(")", "(");
|
||||
}
|
||||
|
||||
|
||||
private final String placeholderPrefix;
|
||||
|
||||
private final String placeholderSuffix;
|
||||
|
||||
private final String simplePrefix;
|
||||
|
||||
private final String valueSeparator;
|
||||
|
||||
private final boolean ignoreUnresolvablePlaceholders;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
|
||||
*
|
||||
* @param placeholderPrefix the prefix that denotes the start of a placeholder
|
||||
* @param placeholderSuffix the suffix that denotes the end of a placeholder
|
||||
* @param valueSeparator the separating character between the placeholder variable
|
||||
* and the associated default value, if any
|
||||
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
|
||||
* be ignored ({@code true}) or cause an exception ({@code false})
|
||||
*/
|
||||
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
|
||||
String valueSeparator, boolean ignoreUnresolvablePlaceholders) {
|
||||
|
||||
requireNonNull((Object) placeholderPrefix, "'placeholderPrefix' must not be null");
|
||||
requireNonNull((Object) placeholderSuffix, "'placeholderSuffix' must not be null");
|
||||
this.placeholderPrefix = placeholderPrefix;
|
||||
this.placeholderSuffix = placeholderSuffix;
|
||||
String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix);
|
||||
if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) {
|
||||
this.simplePrefix = simplePrefixForSuffix;
|
||||
} else {
|
||||
this.simplePrefix = this.placeholderPrefix;
|
||||
}
|
||||
this.valueSeparator = valueSeparator;
|
||||
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces all placeholders of format {@code ${name}} with the value returned
|
||||
* from the supplied {@link PlaceholderResolver}.
|
||||
*
|
||||
* @param value the value containing the placeholders to be replaced
|
||||
* @param placeholderResolver the {@code PlaceholderResolver} to use for replacement
|
||||
* @return the supplied value with placeholders replaced inline
|
||||
*/
|
||||
public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
|
||||
requireNonNull((Object) value, "'value' must not be null");
|
||||
return parseStringValue(value, placeholderResolver, new HashSet<String>());
|
||||
}
|
||||
|
||||
protected String parseStringValue(
|
||||
String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
|
||||
|
||||
StringBuilder result = new StringBuilder(value);
|
||||
|
||||
int startIndex = value.indexOf(this.placeholderPrefix);
|
||||
while (startIndex != -1) {
|
||||
int endIndex = findPlaceholderEndIndex(result, startIndex);
|
||||
if (endIndex != -1) {
|
||||
String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
|
||||
String originalPlaceholder = placeholder;
|
||||
if (!visitedPlaceholders.add(originalPlaceholder)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
|
||||
}
|
||||
// Recursive invocation, parsing placeholders contained in the placeholder key.
|
||||
placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
|
||||
// Now obtain the value for the fully resolved key...
|
||||
String propVal = placeholderResolver.resolvePlaceholder(placeholder);
|
||||
if (propVal == null && this.valueSeparator != null) {
|
||||
int separatorIndex = placeholder.indexOf(this.valueSeparator);
|
||||
if (separatorIndex != -1) {
|
||||
String actualPlaceholder = placeholder.substring(0, separatorIndex);
|
||||
String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
|
||||
propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
|
||||
if (propVal == null) {
|
||||
propVal = defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (propVal != null) {
|
||||
// Recursive invocation, parsing placeholders contained in the
|
||||
// previously resolved placeholder value.
|
||||
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
|
||||
result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Resolved placeholder '" + placeholder + "'");
|
||||
}
|
||||
startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
|
||||
} else if (this.ignoreUnresolvablePlaceholders) {
|
||||
// Proceed with unprocessed value.
|
||||
startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Could not resolve placeholder '" +
|
||||
placeholder + "'" + " in value \"" + value + "\"");
|
||||
}
|
||||
visitedPlaceholders.remove(originalPlaceholder);
|
||||
} else {
|
||||
startIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
|
||||
int index = startIndex + this.placeholderPrefix.length();
|
||||
int withinNestedPlaceholder = 0;
|
||||
while (index < buf.length()) {
|
||||
if (substringMatch(buf, index, this.placeholderSuffix)) {
|
||||
if (withinNestedPlaceholder > 0) {
|
||||
withinNestedPlaceholder--;
|
||||
index = index + this.placeholderSuffix.length();
|
||||
} else {
|
||||
return index;
|
||||
}
|
||||
} else if (substringMatch(buf, index, this.simplePrefix)) {
|
||||
withinNestedPlaceholder++;
|
||||
index = index + this.simplePrefix.length();
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strategy interface used to resolve replacement values for placeholders contained in Strings.
|
||||
*/
|
||||
public interface PlaceholderResolver {
|
||||
|
||||
/**
|
||||
* Resolve the supplied placeholder name to the replacement value.
|
||||
*
|
||||
* @param placeholderName the name of the placeholder to resolve
|
||||
* @return the replacement value, or {@code null} if no replacement is to be made
|
||||
*/
|
||||
String resolvePlaceholder(String placeholderName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the given string matches the given substring
|
||||
* at the given index.
|
||||
*
|
||||
* @param str the original string (or StringBuilder)
|
||||
* @param index the index in the original string to start matching against
|
||||
* @param substring the substring to match at the given index
|
||||
* @return whether the given string matches the given substring
|
||||
*/
|
||||
public static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
|
||||
for (int j = 0; j < substring.length(); j++) {
|
||||
int i = index + j;
|
||||
if (i >= str.length() || str.charAt(i) != substring.charAt(j)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,563 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.common.utils.placeholder;
|
||||
|
||||
import static org.apache.dolphinscheduler.common.Constants.ADD_CHAR;
|
||||
import static org.apache.dolphinscheduler.common.Constants.ADD_STRING;
|
||||
import static org.apache.dolphinscheduler.common.Constants.DIVISION_CHAR;
|
||||
import static org.apache.dolphinscheduler.common.Constants.DIVISION_STRING;
|
||||
import static org.apache.dolphinscheduler.common.Constants.LEFT_BRACE_CHAR;
|
||||
import static org.apache.dolphinscheduler.common.Constants.LEFT_BRACE_STRING;
|
||||
import static org.apache.dolphinscheduler.common.Constants.MULTIPLY_CHAR;
|
||||
import static org.apache.dolphinscheduler.common.Constants.STAR;
|
||||
import static org.apache.dolphinscheduler.common.Constants.N;
|
||||
import static org.apache.dolphinscheduler.common.Constants.P;
|
||||
import static org.apache.dolphinscheduler.common.Constants.RIGHT_BRACE_CHAR;
|
||||
import static org.apache.dolphinscheduler.common.Constants.SUBTRACT_CHAR;
|
||||
import static org.apache.dolphinscheduler.common.Constants.SUBTRACT_STRING;
|
||||
|
||||
import org.apache.dolphinscheduler.common.Constants;
|
||||
import org.apache.dolphinscheduler.common.utils.DateUtils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* time place holder utils
|
||||
*/
|
||||
public class TimePlaceholderUtils {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TimePlaceholderUtils.class);
|
||||
|
||||
/**
|
||||
* Prefix of the position to be replaced
|
||||
*/
|
||||
public static final String PLACEHOLDER_PREFIX = "$[";
|
||||
|
||||
/**
|
||||
* The suffix of the position to be replaced
|
||||
*/
|
||||
public static final String PLACEHOLDER_SUFFIX = "]";
|
||||
|
||||
/**
|
||||
* Replaces all placeholders of format {@code ${name}} with the value returned
|
||||
* from the supplied {@link PropertyPlaceholderHelper.PlaceholderResolver}.
|
||||
*
|
||||
* @param value the value containing the placeholders to be replaced
|
||||
* @param date custom date
|
||||
* @param ignoreUnresolvablePlaceholders ignore unresolvable placeholders
|
||||
* @return the supplied value with placeholders replaced inline
|
||||
*/
|
||||
public static String replacePlaceholders(String value, Date date, boolean ignoreUnresolvablePlaceholders) {
|
||||
PropertyPlaceholderHelper strictHelper = getPropertyPlaceholderHelper(false);
|
||||
PropertyPlaceholderHelper nonStrictHelper = getPropertyPlaceholderHelper(true);
|
||||
|
||||
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
|
||||
return helper.replacePlaceholders(value, new TimePlaceholderResolver(value, date));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
|
||||
*
|
||||
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
|
||||
* be ignored ({@code true}) or cause an exception ({@code false})
|
||||
*/
|
||||
private static PropertyPlaceholderHelper getPropertyPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
|
||||
return new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, null, ignoreUnresolvablePlaceholders);
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate expression's value
|
||||
*
|
||||
* @param expression expression
|
||||
* @return expression's value
|
||||
*/
|
||||
public static Integer calculate(String expression) {
|
||||
expression = StringUtils.trim(expression);
|
||||
expression = convert(expression);
|
||||
|
||||
List<String> result = string2List(expression);
|
||||
result = convert2SuffixList(result);
|
||||
|
||||
return calculate(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the sign in the expression to P (positive) N (negative)
|
||||
*
|
||||
* @param expression
|
||||
* @return eg. "-3+-6*(+8)-(-5) -> S3+S6*(P8)-(S5)"
|
||||
*/
|
||||
private static String convert(String expression) {
|
||||
char[] arr = expression.toCharArray();
|
||||
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (arr[i] == SUBTRACT_CHAR) {
|
||||
if (i == 0) {
|
||||
arr[i] = N;
|
||||
} else {
|
||||
char c = arr[i - 1];
|
||||
if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) {
|
||||
arr[i] = N;
|
||||
}
|
||||
}
|
||||
} else if (arr[i] == ADD_CHAR) {
|
||||
if (i == 0) {
|
||||
arr[i] = P;
|
||||
} else {
|
||||
char c = arr[i - 1];
|
||||
if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) {
|
||||
arr[i] = P;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new String(arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* to suffix expression
|
||||
*
|
||||
* @param srcList
|
||||
* @return
|
||||
*/
|
||||
private static List<String> convert2SuffixList(List<String> srcList) {
|
||||
List<String> result = new ArrayList<>();
|
||||
Stack<String> stack = new Stack<>();
|
||||
|
||||
for (int i = 0; i < srcList.size(); i++) {
|
||||
if (Character.isDigit(srcList.get(i).charAt(0))) {
|
||||
result.add(srcList.get(i));
|
||||
} else {
|
||||
switch (srcList.get(i).charAt(0)) {
|
||||
case LEFT_BRACE_CHAR:
|
||||
stack.push(srcList.get(i));
|
||||
break;
|
||||
case RIGHT_BRACE_CHAR:
|
||||
while (!LEFT_BRACE_STRING.equals(stack.peek())) {
|
||||
result.add(stack.pop());
|
||||
}
|
||||
stack.pop();
|
||||
break;
|
||||
default:
|
||||
while (!stack.isEmpty() && compare(stack.peek(), srcList.get(i))) {
|
||||
result.add(stack.pop());
|
||||
}
|
||||
stack.push(srcList.get(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
result.add(stack.pop());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the suffix expression
|
||||
*
|
||||
* @param result
|
||||
* @return
|
||||
*/
|
||||
private static Integer calculate(List<String> result) {
|
||||
Stack<Integer> stack = new Stack<>();
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
if (Character.isDigit(result.get(i).charAt(0))) {
|
||||
stack.push(Integer.parseInt(result.get(i)));
|
||||
} else {
|
||||
Integer backInt = stack.pop();
|
||||
Integer frontInt = 0;
|
||||
char op = result.get(i).charAt(0);
|
||||
|
||||
if (!(op == P || op == N)) {
|
||||
frontInt = stack.pop();
|
||||
}
|
||||
|
||||
Integer res = 0;
|
||||
switch (result.get(i).charAt(0)) {
|
||||
case P:
|
||||
res = frontInt + backInt;
|
||||
break;
|
||||
case N:
|
||||
res = frontInt - backInt;
|
||||
break;
|
||||
case ADD_CHAR:
|
||||
res = frontInt + backInt;
|
||||
break;
|
||||
case SUBTRACT_CHAR:
|
||||
res = frontInt - backInt;
|
||||
break;
|
||||
case MULTIPLY_CHAR:
|
||||
res = frontInt * backInt;
|
||||
break;
|
||||
case DIVISION_CHAR:
|
||||
res = frontInt / backInt;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
stack.push(res);
|
||||
}
|
||||
}
|
||||
|
||||
return stack.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* string to list
|
||||
*
|
||||
* @param expression
|
||||
* @return list
|
||||
*/
|
||||
private static List<String> string2List(String expression) {
|
||||
List<String> result = new ArrayList<>();
|
||||
String num = "";
|
||||
for (int i = 0; i < expression.length(); i++) {
|
||||
if (Character.isDigit(expression.charAt(i))) {
|
||||
num = num + expression.charAt(i);
|
||||
} else {
|
||||
if (!num.isEmpty()) {
|
||||
result.add(num);
|
||||
}
|
||||
result.add(expression.charAt(i) + "");
|
||||
num = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (!num.isEmpty()) {
|
||||
result.add(num);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* compare loginUser level
|
||||
*
|
||||
* @param peek
|
||||
* @param cur
|
||||
* @return true or false
|
||||
*/
|
||||
private static boolean compare(String peek, String cur) {
|
||||
if (STAR.equals(peek) && (DIVISION_STRING.equals(cur) || STAR.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
|
||||
return true;
|
||||
} else if (DIVISION_STRING.equals(peek) && (DIVISION_STRING.equals(cur) || STAR.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
|
||||
return true;
|
||||
} else if (ADD_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
|
||||
return true;
|
||||
} else {
|
||||
return SUBTRACT_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder replacement resolver
|
||||
*/
|
||||
private static class TimePlaceholderResolver implements
|
||||
PropertyPlaceholderHelper.PlaceholderResolver {
|
||||
|
||||
private final String value;
|
||||
|
||||
private final Date date;
|
||||
|
||||
public TimePlaceholderResolver(String value, Date date) {
|
||||
this.value = value;
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolvePlaceholder(String placeholderName) {
|
||||
try {
|
||||
return calculateTime(placeholderName, date);
|
||||
} catch (Exception ex) {
|
||||
logger.error("resolve placeholder '{}' in [ {} ]", placeholderName, value, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the formatted date according to the corresponding date format
|
||||
*
|
||||
* @param expression date expression
|
||||
* @param date date
|
||||
* @return reformat date
|
||||
*/
|
||||
public static String getPlaceHolderTime(String expression, Date date) {
|
||||
if (StringUtils.isBlank(expression)) {
|
||||
return null;
|
||||
}
|
||||
if (null == date) {
|
||||
return null;
|
||||
}
|
||||
return calculateTime(expression, date);
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate time
|
||||
*
|
||||
* @param date date
|
||||
* @return calculate time
|
||||
*/
|
||||
private static String calculateTime(String expression, Date date) {
|
||||
// After N years: $[add_months(yyyyMMdd,12*N)], the first N months: $[add_months(yyyyMMdd,-N)], etc
|
||||
String value;
|
||||
|
||||
try {
|
||||
if (expression.startsWith(Constants.TIMESTAMP)) {
|
||||
String timeExpression = expression.substring(Constants.TIMESTAMP.length() + 1, expression.length() - 1);
|
||||
|
||||
Map.Entry<Date, String> entry = calcTimeExpression(timeExpression, date);
|
||||
|
||||
String dateStr = DateUtils.format(entry.getKey(), entry.getValue(), null);
|
||||
|
||||
Date timestamp = DateUtils.parse(dateStr, Constants.PARAMETER_FORMAT_TIME, null);
|
||||
|
||||
value = String.valueOf(timestamp.getTime() / 1000);
|
||||
} else {
|
||||
Map.Entry<Date, String> entry = calcTimeExpression(expression, date);
|
||||
value = DateUtils.format(entry.getKey(), entry.getValue(), null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate time expresstion
|
||||
*
|
||||
* @param expression expresstion
|
||||
* @param date date
|
||||
* @return map with date, date format
|
||||
*/
|
||||
public static Map.Entry<Date, String> calcTimeExpression(String expression, Date date) {
|
||||
Map.Entry<Date, String> resultEntry;
|
||||
|
||||
if (expression.startsWith(Constants.ADD_MONTHS)) {
|
||||
resultEntry = calcMonths(expression, date);
|
||||
} else if (expression.startsWith(Constants.MONTH_BEGIN)) {
|
||||
resultEntry = calcMonthBegin(expression, date);
|
||||
} else if (expression.startsWith(Constants.MONTH_END)) {
|
||||
resultEntry = calcMonthEnd(expression, date);
|
||||
} else if (expression.startsWith(Constants.WEEK_BEGIN)) {
|
||||
resultEntry = calcWeekStart(expression, date);
|
||||
} else if (expression.startsWith(Constants.WEEK_END)) {
|
||||
resultEntry = calcWeekEnd(expression, date);
|
||||
} else {
|
||||
resultEntry = calcMinutes(expression, date);
|
||||
}
|
||||
|
||||
return resultEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* get first day of month
|
||||
*
|
||||
* @param expression expresstion
|
||||
* @param date date
|
||||
* @return first day of month
|
||||
*/
|
||||
public static Map.Entry<Date, String> calcMonthBegin(String expression, Date date) {
|
||||
String addMonthExpr = expression.substring(Constants.MONTH_BEGIN.length() + 1, expression.length() - 1);
|
||||
String[] params = addMonthExpr.split(Constants.COMMA);
|
||||
|
||||
if (params.length == 2) {
|
||||
String dateFormat = params[0];
|
||||
String dayExpr = params[1];
|
||||
Integer day = calculate(dayExpr);
|
||||
Date targetDate = DateUtils.getFirstDayOfMonth(date);
|
||||
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
|
||||
|
||||
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
|
||||
}
|
||||
|
||||
throw new RuntimeException("expression not valid");
|
||||
}
|
||||
|
||||
/**
|
||||
* get last day of month
|
||||
*
|
||||
* @param expression expresstion
|
||||
* @param date date
|
||||
* @return last day of month
|
||||
*/
|
||||
public static Map.Entry<Date, String> calcMonthEnd(String expression, Date date) {
|
||||
String addMonthExpr = expression.substring(Constants.MONTH_END.length() + 1, expression.length() - 1);
|
||||
String[] params = addMonthExpr.split(Constants.COMMA);
|
||||
|
||||
if (params.length == 2) {
|
||||
String dateFormat = params[0];
|
||||
String dayExpr = params[1];
|
||||
Integer day = calculate(dayExpr);
|
||||
Date targetDate = DateUtils.getLastDayOfMonth(date);
|
||||
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
|
||||
|
||||
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
|
||||
}
|
||||
|
||||
throw new RuntimeException("expression not valid");
|
||||
}
|
||||
|
||||
/**
|
||||
* get first day of week
|
||||
*
|
||||
* @param expression expresstion
|
||||
* @param date date
|
||||
* @return monday
|
||||
*/
|
||||
public static Map.Entry<Date, String> calcWeekStart(String expression, Date date) {
|
||||
String addMonthExpr = expression.substring(Constants.WEEK_BEGIN.length() + 1, expression.length() - 1);
|
||||
String[] params = addMonthExpr.split(Constants.COMMA);
|
||||
|
||||
if (params.length == 2) {
|
||||
String dateFormat = params[0];
|
||||
String dayExpr = params[1];
|
||||
Integer day = calculate(dayExpr);
|
||||
Date targetDate = DateUtils.getMonday(date);
|
||||
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
|
||||
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
|
||||
}
|
||||
|
||||
throw new RuntimeException("expression not valid");
|
||||
}
|
||||
|
||||
/**
|
||||
* get last day of week
|
||||
*
|
||||
* @param expression expresstion
|
||||
* @param date date
|
||||
* @return last day of week
|
||||
*/
|
||||
public static Map.Entry<Date, String> calcWeekEnd(String expression, Date date) {
|
||||
String addMonthExpr = expression.substring(Constants.WEEK_END.length() + 1, expression.length() - 1);
|
||||
String[] params = addMonthExpr.split(Constants.COMMA);
|
||||
|
||||
if (params.length == 2) {
|
||||
String dateFormat = params[0];
|
||||
String dayExpr = params[1];
|
||||
Integer day = calculate(dayExpr);
|
||||
Date targetDate = DateUtils.getSunday(date);
|
||||
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
|
||||
|
||||
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Expression not valid");
|
||||
}
|
||||
|
||||
/**
|
||||
* calc months expression
|
||||
*
|
||||
* @param expression expresstion
|
||||
* @param date date
|
||||
* @return calc months
|
||||
*/
|
||||
public static Map.Entry<Date, String> calcMonths(String expression, Date date) {
|
||||
String addMonthExpr = expression.substring(Constants.ADD_MONTHS.length() + 1, expression.length() - 1);
|
||||
String[] params = addMonthExpr.split(Constants.COMMA);
|
||||
|
||||
if (params.length == 2) {
|
||||
String dateFormat = params[0];
|
||||
String monthExpr = params[1];
|
||||
Integer addMonth = calculate(monthExpr);
|
||||
Date targetDate = org.apache.commons.lang.time.DateUtils.addMonths(date, addMonth);
|
||||
|
||||
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
|
||||
}
|
||||
|
||||
throw new RuntimeException("expression not valid");
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate time expression
|
||||
*
|
||||
* @param expression expresstion
|
||||
* @param date date
|
||||
* @return calculate time expression with date,format
|
||||
*/
|
||||
public static Map.Entry<Date, String> calcMinutes(String expression, Date date) {
|
||||
if (expression.contains("+")) {
|
||||
int index = expression.lastIndexOf('+');
|
||||
|
||||
if (Character.isDigit(expression.charAt(index + 1))) {
|
||||
String addMinuteExpr = expression.substring(index + 1);
|
||||
Date targetDate = org.apache.commons.lang3.time.DateUtils
|
||||
.addMinutes(date, calcMinutes(addMinuteExpr));
|
||||
String dateFormat = expression.substring(0, index);
|
||||
|
||||
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
|
||||
}
|
||||
} else if (expression.contains("-")) {
|
||||
int index = expression.lastIndexOf('-');
|
||||
|
||||
if (Character.isDigit(expression.charAt(index + 1))) {
|
||||
String addMinuteExpr = expression.substring(index + 1);
|
||||
Date targetDate = org.apache.commons.lang.time.DateUtils
|
||||
.addMinutes(date, 0 - calcMinutes(addMinuteExpr));
|
||||
String dateFormat = expression.substring(0, index);
|
||||
|
||||
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
|
||||
}
|
||||
|
||||
// yyyy-MM-dd/HH:mm:ss
|
||||
return new AbstractMap.SimpleImmutableEntry<>(date, expression);
|
||||
}
|
||||
|
||||
// $[HHmmss]
|
||||
return new AbstractMap.SimpleImmutableEntry<>(date, expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate need minutes
|
||||
*
|
||||
* @param minuteExpression minute expression
|
||||
* @return calculate need minutes
|
||||
*/
|
||||
public static Integer calcMinutes(String minuteExpression) {
|
||||
int index = minuteExpression.indexOf('/');
|
||||
|
||||
String calcExpression;
|
||||
|
||||
if (index == -1) {
|
||||
calcExpression = String.format("60*24*(%s)", minuteExpression);
|
||||
} else {
|
||||
|
||||
calcExpression = String.format("60*24*(%s)%s", minuteExpression.substring(0, index),
|
||||
minuteExpression.substring(index));
|
||||
}
|
||||
|
||||
return calculate(calcExpression);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,10 +17,11 @@
|
|||
|
||||
package org.apache.dolphinscheduler.common.utils;
|
||||
|
||||
import static org.apache.dolphinscheduler.common.utils.placeholder.TimePlaceholderUtils.replacePlaceholders;
|
||||
|
||||
import static org.apache.dolphinscheduler.plugin.task.api.parser.TimePlaceholderUtils.replacePlaceholders;
|
||||
|
||||
import org.apache.dolphinscheduler.common.Constants;
|
||||
import org.apache.dolphinscheduler.common.utils.placeholder.PlaceholderUtils;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parser.PlaceholderUtils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.dolphinscheduler.common.utils.placeholder;
|
||||
|
||||
import org.apache.dolphinscheduler.common.utils.DateUtils;
|
||||
import org.apache.dolphinscheduler.plugin.task.api.parser.TimePlaceholderUtils;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
|
|
|||
Loading…
Reference in New Issue