001    package org.andromda.core.common;
002    
003    import org.apache.commons.lang.StringUtils;
004    
005    /**
006     * Contains Exception handling utilities.
007     *
008     * @author Chad Brandon
009     */
010    public class ExceptionUtils
011    {
012        /**
013         * Checks if the argument is null, and if so, throws an IllegalArgumentException, does nothing if not.
014         *
015         * @param methodExecuteName the name of the method we are currently executing
016         * @param argumentName the name of the argument we are checking for null
017         * @param argument the argument we are checking
018         * @deprecated used {@link #checkNull(String, Object)} instead since we can detect the method name.
019         */
020        @Deprecated
021        public static void checkNull(
022            final String methodExecuteName,
023            final String argumentName,
024            final Object argument)
025        {
026            checkNull(
027                argumentName,
028                argument,
029                3);
030        }
031    
032        /**
033         * Checks if the argument is null, and if so, throws an IllegalArgumentException, does nothing if not.
034         *
035         * @param argumentName the name of the argument we are checking for null
036         * @param argument the argument we are checking
037         */
038        public static void checkNull(
039            final String argumentName,
040            final Object argument)
041        {
042            checkNull(
043                argumentName,
044                argument,
045                3);
046        }
047    
048        /**
049         * Checks if the argument is null, and if so, throws an IllegalArgumentException, does nothing if not.
050         *
051         * @param argumentName the name of the argument we are checking for null
052         * @param argument the argument we are checking
053         * @param stackDepth the depth of the stack from which to retrieve the methodInformation.
054         */
055        private static void checkNull(
056            final String argumentName,
057            final Object argument,
058            final int stackDepth)
059        {
060            if (StringUtils.isEmpty(argumentName))
061            {
062                throw new IllegalArgumentException("'argumentName' can not be null or an empty String");
063            }
064    
065            if (argument == null)
066            {
067                throw new IllegalArgumentException(getMethodName(stackDepth) + " - '" + argumentName + "' can not be null");
068            }
069        }
070    
071        /**
072         * Checks if the argument is null or an empty String throws an IllegalArgumentException if it is, does nothing if
073         * not.
074         *
075         * @param methodExecuteName the name of the method we are currently executing
076         * @param argumentName the name of the argument we are checking for null
077         * @param argument the argument we are checking
078         * @deprecated use {@link #checkEmpty(String, String)} instead since we can detect the method name.
079         */
080        @Deprecated
081        public static void checkEmpty(
082            final String methodExecuteName,
083            final String argumentName,
084            final String argument)
085        {
086            checkEmpty(
087                argumentName,
088                argument,
089                3);
090        }
091    
092        /**
093         * Checks if the argument is null or an empty String throws an IllegalArgumentException if it is, does nothing if
094         * not.
095         *
096         * @param argumentName the name of the argument we are checking for null
097         * @param argument the argument we are checking
098         */
099        public static void checkEmpty(
100            final String argumentName,
101            final String argument)
102        {
103            checkEmpty(
104                argumentName,
105                argument,
106                3);
107        }
108    
109        /**
110         * Checks if the argument is null or an empty String throws an IllegalArgumentException if it is, does nothing if
111         * not.
112         *
113         * @param argumentName the name of the argument we are checking for null
114         * @param argument the argument we are checking
115         * @param stackDepth the depth of the stack from which to retrieve the methodInformation.
116         */
117        private static void checkEmpty(
118            final String argumentName,
119            final String argument,
120            final int stackDepth)
121        {
122            if (StringUtils.isEmpty(argumentName))
123            {
124                throw new IllegalArgumentException("'argumentName' can not be null or an empty String");
125            }
126            if (StringUtils.isEmpty(argument))
127            {
128                throw new IllegalArgumentException(getMethodName(stackDepth) + " - '" + argumentName +
129                    "' can not be null or an empty String");
130            }
131        }
132    
133        /**
134         * Checks if the argumentClass is assignable to assignableToClass, and if not throws an IllegalArgumentException,
135         * otherwise does nothing.
136         *
137         * @param methodExecuteName the method name of the method, this method is being executed within
138         * @param assignableToClass the Class that argumentClass must be assignable to
139         * @param argumentClass the argumentClass we are checking
140         * @param argumentName the name of the argument we are checking
141         * @deprecated use {@link #checkAssignable(Class, String, Class)} since we can detect the method name.
142         */
143        @Deprecated
144        public static void checkAssignable(
145            final String methodExecuteName,
146            final Class assignableToClass,
147            final String argumentName,
148            final Class argumentClass)
149        {
150            checkAssignable(
151                assignableToClass,
152                argumentName,
153                argumentClass,
154                3);
155        }
156    
157        /**
158         * Checks if the argumentClass is assignable to assignableToClass, and if not throws an IllegalArgumentException,
159         * otherwise does nothing.
160         *
161         * @param assignableToClass the Class that argumentClass must be assignable to
162         * @param argumentClass the argumentClass we are checking
163         * @param argumentName the name of the argument we are checking
164         */
165        public static void checkAssignable(
166            final Class assignableToClass,
167            final String argumentName,
168            final Class argumentClass)
169        {
170            checkAssignable(
171                assignableToClass,
172                argumentName,
173                argumentClass,
174                3);
175        }
176    
177        /**
178         * Checks if the argumentClass is assignable to assignableToClass, and if not throws an IllegalArgumentException,
179         * otherwise does nothing.
180         *
181         * @param assignableToClass the Class that argumentClass must be assignable to
182         * @param argumentClass the argumentClass we are checking
183         * @param argumentName the name of the argument we are checking
184         * @param stackDepth the depth of the stack from which to retrieve the method information.
185         */
186        private static void checkAssignable(
187            final Class assignableToClass,
188            final String argumentName,
189            final Class argumentClass,
190            final int stackDepth)
191        {
192            if (assignableToClass == null)
193            {
194                throw new IllegalArgumentException("'assignableToClass' can not be null");
195            }
196            if (argumentClass == null)
197            {
198                throw new IllegalArgumentException("'argumentClass' can not be null");
199            }
200            if (StringUtils.isEmpty(argumentName))
201            {
202                throw new IllegalArgumentException("'argumentName can not be null or an empty String");
203            }
204    
205            // this is what the method is for
206            if (!assignableToClass.isAssignableFrom(argumentClass))
207            {
208                throw new IllegalArgumentException(getMethodName(stackDepth) + " - '" + argumentName + "' class --> '" +
209                    argumentClass + "' must be assignable to class --> '" + assignableToClass + '\'');
210            }
211        }
212    
213        /**
214         * Attempts to retrieve the root cause of the exception, if it can not be
215         * found, the <code>throwable</code> itself is returned.
216         *
217         * @param throwable the exception from which to retrieve the root cause.
218         * @return the root cause of the exception
219         */
220        public static Throwable getRootCause(Throwable throwable)
221        {
222            final Throwable root = org.apache.commons.lang.exception.ExceptionUtils.getRootCause(throwable);
223            if (root != null)
224            {
225                throwable = root;
226            }
227            return throwable;
228        }
229    
230        /**
231         * Gets the appropriate method name for the method being checked.
232         *
233         * @return the name of the method.
234         */
235        private static String getMethodName(int stackDepth)
236        {
237            String methodName = null;
238            final Throwable throwable = new Throwable();
239            final StackTraceElement[] stack = throwable.getStackTrace();
240            if (stack.length >= stackDepth)
241            {
242                final StackTraceElement element = stack[stackDepth];
243                methodName = element.getClassName() + '.' + element.getMethodName();
244            }
245            return methodName;
246        }
247    }