001    /**
002     * Copyright (c) 2010 Yahoo! Inc. All rights reserved.
003     * Licensed under the Apache License, Version 2.0 (the "License");
004     * you may not use this file except in compliance with the License.
005     * You may obtain a copy of the License at
006     *
007     *   http://www.apache.org/licenses/LICENSE-2.0
008     *
009     *  Unless required by applicable law or agreed to in writing, software
010     *  distributed under the License is distributed on an "AS IS" BASIS,
011     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012     *  See the License for the specific language governing permissions and
013     *  limitations under the License. See accompanying LICENSE file.
014     */
015    package org.apache.oozie.util;
016    
017    import java.util.Date;
018    import java.util.List;
019    import java.util.TimeZone;
020    
021    /**
022     * Utility class to check common parameter preconditions.
023     */
024    public class ParamChecker {
025    
026        /**
027         * Check that a value is not null. If null throws an IllegalArgumentException.
028         *
029         * @param obj value.
030         * @param name parameter name for the exception message.
031         * @return the given value.
032         */
033        public static <T> T notNull(T obj, String name) {
034            if (obj == null) {
035                throw new IllegalArgumentException(name + " cannot be null");
036            }
037            return obj;
038        }
039    
040        /**
041         * Check that a list is not null and that none of its elements is null. If null or if the list has emtpy elements
042         * throws an IllegalArgumentException.
043         *
044         * @param list the list of strings.
045         * @param name parameter name for the exception message.
046         * @return the given list.
047         */
048        public static <T> List<T> notNullElements(List<T> list, String name) {
049            notNull(list, name);
050            for (int i = 0; i < list.size(); i++) {
051                notNull(list.get(i), XLog.format("list [{0}] element [{1}]", name, i));
052            }
053            return list;
054        }
055    
056        /**
057         * Check that a string is not null and not empty. If null or emtpy throws an IllegalArgumentException.
058         *
059         * @param str value.
060         * @param name parameter name for the exception message.
061         * @return the given value.
062         */
063        public static String notEmpty(String str, String name) {
064            if (str == null) {
065                throw new IllegalArgumentException(name + " cannot be null");
066            }
067            if (str.length() == 0) {
068                throw new IllegalArgumentException(name + " cannot be empty");
069            }
070            return str;
071        }
072    
073        /**
074         * Check that a list is not null and that none of its elements is null. If null or if the list has emtpy elements
075         * throws an IllegalArgumentException.
076         *
077         * @param list the list of strings.
078         * @param name parameter name for the exception message.
079         * @return the given list.
080         */
081        public static List<String> notEmptyElements(List<String> list, String name) {
082            notNull(list, name);
083            for (int i = 0; i < list.size(); i++) {
084                notEmpty(list.get(i), XLog.format("list [{0}] element [{1}]", name, i));
085            }
086            return list;
087        }
088    
089        private static final int MAX_NODE_NAME_LEN = 50;
090    
091        /**
092         * Check that the given string is a valid action name [a-zA-Z_][0-9a-zA-Z_\-]* and not longer than 50 chars.
093         *
094         * @param actionName string to validate is a token.
095         * @return the given string.
096         */
097        public static String validateActionName(String actionName) {
098            ParamChecker.notEmpty(actionName, "action name");
099            if (actionName.length() > MAX_NODE_NAME_LEN) {
100                throw new IllegalArgumentException(XLog.format("name [{0}] must be {1} chars or less", actionName,
101                                                               MAX_NODE_NAME_LEN));
102            }
103    
104            char c = actionName.charAt(0);
105            if (!(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') && !(c == '_')) {
106                throw new IllegalArgumentException(XLog.format("name [{0}], must start with [A-Za-z_]", actionName));
107            }
108            for (int i = 1; i < actionName.length(); i++) {
109                c = actionName.charAt(i);
110                if (!(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z')
111                        && !(c == '_' || c == '-')) {
112                    throw new IllegalArgumentException(XLog.format("name [{0}] must be [A-Za-z_][0-9A-Za-z_]*", actionName));
113                }
114            }
115            return actionName;
116        }
117    
118        /**
119         * Return if the specified token is a valid Java identifier.
120         *
121         * @param token string to validate if it is a valid Java identifier.
122         * @return if the specified token is a valid Java identifier.
123         */
124        public static boolean isValidIdentifier(String token) {
125            ParamChecker.notEmpty(token, "identifier");
126            for (int i = 0; i < token.length(); i++) {
127                char c = token.charAt(i);
128                if (!(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z') && !(c == '_')) {
129                    return false;
130                }
131                if (i == 0 && (c >= '0' && c <= '9')) {
132                    return false;
133                }
134            }
135            return true;
136        }
137    
138        /**
139         * Check whether the value is greater than or equals 0.
140         *
141         * @param value : value to test
142         * @param name : Name of the parameter
143         * @return If the value is > 0, return the value. Otherwise throw IllegalArgumentException
144         */
145        public static int checkGTZero(int value, String name) {
146            if (value <= 0) {
147                throw new IllegalArgumentException(XLog.format("parameter [{0}] = [{1}] must be greater than zero", name,
148                                                               value));
149            }
150            return value;
151        }
152    
153        /**
154         * Check whether the value is greater than or equals to 0.
155         *
156         * @param value : value to test
157         * @param name : Name of the parameter
158         * @return If the value is >= 0, return the value. Otherwise throw IllegalArgumentException
159         */
160        public static int checkGEZero(int value, String name) {
161            if (value < 0) {
162                throw new IllegalArgumentException(XLog.format(
163                        "parameter [{0}] = [{1}] must be greater than or equals zero", name, value));
164            }
165            return value;
166        }
167    
168        /**
169         * Check whether the value is Integer.
170         *
171         * @param value : value to test
172         * @param name : Name of the parameter
173         * @return If the value is integer, return the value. Otherwise throw IllegalArgumentException
174         */
175        public static int checkInteger(String val, String name) {
176            int ret;
177            try {
178                ret = Integer.parseInt(val);
179            }
180            catch (NumberFormatException nex) {
181                throw new IllegalArgumentException(XLog.format(
182                        "parameter [{0}] = [{1}]  must be an integer. Parsing error {2}", name, val, nex));
183            }
184            return ret;
185        }
186    
187        /**
188         * Check whether the value is UTC data format.
189         *
190         * @param value : value to test
191         * @param name : Name of the parameter
192         * @return If the value is in UTC date format, return the value. Otherwise throw IllegalArgumentException
193         */
194        public static Date checkUTC(String date, String name) {
195            Date ret;
196            try {
197                ret = DateUtils.parseDateUTC(date);
198            }
199            catch (Exception ex) {
200                throw new IllegalArgumentException(XLog.format(
201                        "parameter [{0}] = [{1}] must be Date in UTC format (yyyy-MM-dd'T'HH:mm'Z')."
202                                + " Parsing error {2}", name, date, ex));
203            }
204            return ret;
205        }
206    
207        /**
208         * Check whether the value mention correct Timezone.
209         *
210         * @param value : value to test
211         * @param name : Name of the parameter
212         * @return If the value is correct TZ return the value. Otherwise throw IllegalArgumentException
213         */
214        public static TimeZone checkTimeZone(String tzStr, String name) {
215            TimeZone tz;
216            try {
217                tz = DateUtils.getTimeZone(tzStr);
218            }
219            catch (Exception ex) {
220                throw new IllegalArgumentException(XLog.format("parameter [{0}] = [{1}] must be a valid TZ."
221                        + " Parsing error {2}", name, tzStr, ex));
222            }
223            return tz;
224        }
225    
226        /**
227         * Check whether an item is a member of an array of string
228         *
229         * @param item : item to test
230         * @param members : List of items in string
231         * @param name : Name of the parameter
232         * @return If the item is in the member return true. Otherwise throw IllegalArgumentException
233         */
234        public static boolean isMember(String item, String[] members, String name) {
235            for (int i = 0; i < members.length; i++) {
236                if (members[i].equals(item)) {
237                    return true;
238                }
239            }
240            // Error case
241            StringBuilder buff = new StringBuilder();
242            for (int i = 0; i < members.length; i++) {
243                buff.append(members[i]).append(", ");
244            }
245            throw new IllegalArgumentException(XLog.format("parameter [{0}] = [{1}] " + "must be in the list {2}", name,
246                                                           item, buff.toString()));
247        }
248    }