001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019package org.apache.hadoop.lib.util;
020
021import org.apache.hadoop.classification.InterfaceAudience;
022
023import java.text.MessageFormat;
024import java.util.List;
025import java.util.regex.Pattern;
026
027/**
028 * Utility methods to check preconditions.
029 * <p/>
030 * Commonly used for method arguments preconditions.
031 */
032@InterfaceAudience.Private
033public class Check {
034
035  /**
036   * Verifies a variable is not NULL.
037   *
038   * @param obj the variable to check.
039   * @param name the name to use in the exception message.
040   *
041   * @return the variable.
042   *
043   * @throws IllegalArgumentException if the variable is NULL.
044   */
045  public static <T> T notNull(T obj, String name) {
046    if (obj == null) {
047      throw new IllegalArgumentException(name + " cannot be null");
048    }
049    return obj;
050  }
051
052  /**
053   * Verifies a list does not have any NULL elements.
054   *
055   * @param list the list to check.
056   * @param name the name to use in the exception message.
057   *
058   * @return the list.
059   *
060   * @throws IllegalArgumentException if the list has NULL elements.
061   */
062  public static <T> List<T> notNullElements(List<T> list, String name) {
063    notNull(list, name);
064    for (int i = 0; i < list.size(); i++) {
065      notNull(list.get(i), MessageFormat.format("list [{0}] element [{1}]", name, i));
066    }
067    return list;
068  }
069
070  /**
071   * Verifies a string is not NULL and not emtpy
072   *
073   * @param str the variable to check.
074   * @param name the name to use in the exception message.
075   *
076   * @return the variable.
077   *
078   * @throws IllegalArgumentException if the variable is NULL or empty.
079   */
080  public static String notEmpty(String str, String name) {
081    if (str == null) {
082      throw new IllegalArgumentException(name + " cannot be null");
083    }
084    if (str.length() == 0) {
085      throw new IllegalArgumentException(name + " cannot be empty");
086    }
087    return str;
088  }
089
090  /**
091   * Verifies a string list is not NULL and not emtpy
092   *
093   * @param list the list to check.
094   * @param name the name to use in the exception message.
095   *
096   * @return the variable.
097   *
098   * @throws IllegalArgumentException if the string list has NULL or empty
099   * elements.
100   */
101  public static List<String> notEmptyElements(List<String> list, String name) {
102    notNull(list, name);
103    for (int i = 0; i < list.size(); i++) {
104      notEmpty(list.get(i), MessageFormat.format("list [{0}] element [{1}]", name, i));
105    }
106    return list;
107  }
108
109  private static final String IDENTIFIER_PATTERN_STR = "[a-zA-z_][a-zA-Z0-9_\\-]*";
110
111  private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^" + IDENTIFIER_PATTERN_STR + "$");
112
113  /**
114   * Verifies a value is a valid identifier,
115   * <code>[a-zA-z_][a-zA-Z0-9_\-]*</code>, up to a maximum length.
116   *
117   * @param value string to check if it is a valid identifier.
118   * @param maxLen maximun length.
119   * @param name the name to use in the exception message.
120   *
121   * @return the value.
122   *
123   * @throws IllegalArgumentException if the string is not a valid identifier.
124   */
125  public static String validIdentifier(String value, int maxLen, String name) {
126    Check.notEmpty(value, name);
127    if (value.length() > maxLen) {
128      throw new IllegalArgumentException(
129        MessageFormat.format("[{0}] = [{1}] exceeds max len [{2}]", name, value, maxLen));
130    }
131    if (!IDENTIFIER_PATTERN.matcher(value).find()) {
132      throw new IllegalArgumentException(
133        MessageFormat.format("[{0}] = [{1}] must be '{2}'", name, value, IDENTIFIER_PATTERN_STR));
134    }
135    return value;
136  }
137
138  /**
139   * Verifies an integer is greater than zero.
140   *
141   * @param value integer value.
142   * @param name the name to use in the exception message.
143   *
144   * @return the value.
145   *
146   * @throws IllegalArgumentException if the integer is zero or less.
147   */
148  public static int gt0(int value, String name) {
149    return (int) gt0((long) value, name);
150  }
151
152  /**
153   * Verifies an long is greater than zero.
154   *
155   * @param value long value.
156   * @param name the name to use in the exception message.
157   *
158   * @return the value.
159   *
160   * @throws IllegalArgumentException if the long is zero or less.
161   */
162  public static long gt0(long value, String name) {
163    if (value <= 0) {
164      throw new IllegalArgumentException(
165        MessageFormat.format("parameter [{0}] = [{1}] must be greater than zero", name, value));
166    }
167    return value;
168  }
169
170  /**
171   * Verifies an integer is greater or equal to zero.
172   *
173   * @param value integer value.
174   * @param name the name to use in the exception message.
175   *
176   * @return the value.
177   *
178   * @throws IllegalArgumentException if the integer is greater or equal to zero.
179   */
180  public static int ge0(int value, String name) {
181    return (int) ge0((long) value, name);
182  }
183
184  /**
185   * Verifies an long is greater or equal to zero.
186   *
187   * @param value integer value.
188   * @param name the name to use in the exception message.
189   *
190   * @return the value.
191   *
192   * @throws IllegalArgumentException if the long is greater or equal to zero.
193   */
194  public static long ge0(long value, String name) {
195    if (value < 0) {
196      throw new IllegalArgumentException(MessageFormat.format(
197        "parameter [{0}] = [{1}] must be greater than or equals zero", name, value));
198    }
199    return value;
200  }
201
202}