blob: a4e1e664be5a50f65df36a794b4c09d8f4f77ea1 [file] [log] [blame]
/**
* 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.oozie.util;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.TimeZone;
import org.apache.commons.lang3.StringUtils;
import org.quartz.CronExpression;
import java.text.ParseException;
/**
* Utility class to check common parameter preconditions.
*/
public class ParamChecker {
private static final int MAX_NODE_NAME_LEN = 128;
/**
* Check that a string is not null and not empty. If null or emtpy throws an IllegalArgumentException.
*
* @param str value.
* @param name parameter name for the exception message.
* @return the given value.
*/
public static String notEmpty(String str, String name) {
return notEmpty(str, name, null);
}
/**
* Check that a string is not null and not empty. If null or emtpy throws an IllegalArgumentException.
*
* @param str value.
* @param name parameter name for the exception message.
* @param info additional information to be printed with the exception message
* @return the given value.
*/
public static String notEmpty(String str, String name, String info) {
if (str == null) {
throw new IllegalArgumentException(name + " cannot be null" + (info == null ? "" : ", " + info));
}
if (str.length() == 0) {
throw new IllegalArgumentException(name + " cannot be empty" + (info == null ? "" : ", " + info));
}
return str;
}
/**
* Check that a list is not null and that none of its elements is null. If null or if the list has emtpy elements
* throws an IllegalArgumentException.
*
* @param list the list of strings.
* @param name parameter name for the exception message.
* @return the given list.
*/
public static List<String> notEmptyElements(List<String> list, String name) {
Objects.requireNonNull(list, () -> String.format("%s cannot be null", name));
for (int i = 0; i < list.size(); i++) {
notEmpty(list.get(i), XLog.format("list [{0}] element [{1}]", name, i));
}
return list;
}
/**
* Check that the given string is a valid action name [a-zA-Z_][0-9a-zA-Z_\-]* and not longer than 128 chars.
*
* @param actionName string to validate is a token.
* @return the given string.
*/
public static String validateActionName(String actionName) {
ParamChecker.notEmpty(actionName, "action name");
if (actionName.length() > MAX_NODE_NAME_LEN) {
throw new IllegalArgumentException(XLog.format("name [{0}] must be {1} chars or less", actionName,
MAX_NODE_NAME_LEN));
}
char c = actionName.charAt(0);
if (!(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') && !(c == '_')) {
throw new IllegalArgumentException(XLog.format("name [{0}], must start with [A-Za-z_]", actionName));
}
for (int i = 1; i < actionName.length(); i++) {
c = actionName.charAt(i);
if (!(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z')
&& !(c == '_' || c == '-')) {
throw new IllegalArgumentException(XLog.format("name [{0}] must be [A-Za-z_][0-9A-Za-z_]*", actionName));
}
}
return actionName;
}
/**
* Return if the specified token is a valid Java identifier.
*
* @param token string to validate if it is a valid Java identifier.
* @return if the specified token is a valid Java identifier.
*/
public static boolean isValidIdentifier(String token) {
ParamChecker.notEmpty(token, "identifier");
for (int i = 0; i < token.length(); i++) {
char c = token.charAt(i);
if (!(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') && !(c == '_')) {
return false;
}
if (i == 0 && (c >= '0' && c <= '9')) {
return false;
}
}
return true;
}
/**
* Check whether the value is greater than or equals 0.
*
* @param value : value to test
* @param name : Name of the parameter
* @return If the value is &gt; 0, return the value. Otherwise throw IllegalArgumentException
*/
public static int checkGTZero(int value, String name) {
if (value <= 0) {
throw new IllegalArgumentException(XLog.format("parameter [{0}] = [{1}] must be greater than zero", name,
value));
}
return value;
}
/**
* Check whether the value is greater than or equals to 0.
*
* @param value : value to test
* @param name : Name of the parameter
* @return If the value is &gt;= 0, return the value. Otherwise throw IllegalArgumentException
*/
public static int checkGEZero(int value, String name) {
if (value < 0) {
throw new IllegalArgumentException(XLog.format(
"parameter [{0}] = [{1}] must be greater than or equals zero", name, value));
}
return value;
}
/**
* Check whether the value is less than or equal to 0.
*
* @param value : value to test
* @param name : Name of the parameter
* @return If the value is &lt;= 0, return the value. Otherwise throw IllegalArgumentException
*/
public static int checkLEZero(int value, String name) {
if (value > 0) {
throw new IllegalArgumentException(XLog.format(
"parameter [{0}] = [{1}] must be less than or equal to zero", name, value));
}
return value;
}
/**
* Check whether the value is Integer.
*
* @param val : value to test
* @param name : Name of the parameter
* @return If the value is integer, return the value. Otherwise throw IllegalArgumentException
*/
public static int checkInteger(String val, String name) {
int ret;
try {
ret = Integer.parseInt(val);
}
catch (NumberFormatException nex) {
throw new IllegalArgumentException(XLog.format(
"parameter [{0}] = [{1}] must be an integer. Parsing error {2}", name, val, nex.getMessage(), nex));
}
return ret;
}
/**
* Check whether a value is a valid coordinator frequency.
*
* @param val : value to test
* @return If the value is a valid frequency, return the frequency, Otherwise throw IllegalArgumentException
*/
public static String checkFrequency(String val) {
try {
Integer.parseInt(val);
}
catch (NumberFormatException ex) {
try {
// this part is necessary since Quartz
// doesn't support for specifying both a day-of-week
// and a day-of-month parameter, nor does it support
// using "?" in both fields, but we don't want to
// expose it to users.
String[] cronArray1 = val.split(" ");
String[] cronArray2 = val.split(" ");
if (cronArray1.length != 5) {
throw new IllegalArgumentException(XLog.format(
"parameter [{0}] = [{1}] must have 5 bit fields. Parsing error {2}", "frequency",
val, ex.getMessage(), ex));
}
if (!cronArray1[4].trim().equals("?")) {
cronArray1[2] = "?";
}
if (!cronArray2[2].trim().equals("?")) {
cronArray2[4] = "?";
}
new CronExpression("0 " + StringUtils.join(cronArray1, " "));
new CronExpression("0 " + StringUtils.join(cronArray2, " "));
}
catch (ParseException pex) {
throw new IllegalArgumentException(XLog.format(
"parameter [{0}] = [{1}] must be an integer or a cron syntax. Parsing error {2}", "frequency",
val, ex.getMessage(), ex));
}
}
return val;
}
/**
* Check whether the value is Oozie processing timezone data format.
*
* @param date : date to test
* @param name : Name of the parameter
* @return If the value is in Oozie processing timezone date format, return the value.
* Otherwise throw IllegalArgumentException
*/
public static Date checkDateOozieTZ(String date, String name) {
Date ret;
try {
ret = DateUtils.parseDateOozieTZ(date);
}
catch (Exception ex) {
throw new IllegalArgumentException(XLog.format(
"parameter [{0}] = [{1}] must be Date in {2} format ({3})."
+ " Parsing error {4}", name, date, DateUtils.getOozieProcessingTimeZone().getID(),
DateUtils.getOozieTimeMask(), ex));
}
return ret;
}
/**
* Check whether the value mention correct Timezone.
*
* @param tzStr : timezone to test
* @param name : Name of the parameter
* @return If the value is correct TZ return the value. Otherwise throw IllegalArgumentException
*/
public static TimeZone checkTimeZone(String tzStr, String name) {
TimeZone tz;
try {
tz = DateUtils.getTimeZone(tzStr);
}
catch (Exception ex) {
throw new IllegalArgumentException(XLog.format("parameter [{0}] = [{1}] must be a valid TZ."
+ " Parsing error {2}", name, tzStr, ex.getMessage(), ex));
}
return tz;
}
/**
* Check whether an item is a member of an array of string
*
* @param item : item to test
* @param members : List of items in string
* @param name : Name of the parameter
* @return If the item is in the member return true. Otherwise throw IllegalArgumentException
*/
public static boolean isMember(String item, String[] members, String name) {
for (int i = 0; i < members.length; i++) {
if (members[i].equals(item)) {
return true;
}
}
// Error case
StringBuilder buff = new StringBuilder();
for (int i = 0; i < members.length; i++) {
buff.append(members[i]).append(", ");
}
throw new IllegalArgumentException(XLog.format("parameter [{0}] = [{1}] " + "must be in the list {2}", name,
item, buff.toString()));
}
}