001    /*
002     * Created on Dec 13, 2008
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005     * in compliance with the License. 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 distributed under the License
010     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011     * or implied. See the License for the specific language governing permissions and limitations under
012     * the License.
013     *
014     * Copyright @2008-2010 the original author or authors.
015     */
016    package org.fest.util;
017    
018    import static org.fest.util.Collections.list;
019    
020    import java.util.ArrayList;
021    import java.util.List;
022    
023    import org.fest.util.StackTraces;
024    
025    /**
026     * Understands utility methods related to <code>{@link Throwable}</code>s.
027     *
028     * @author Alex Ruiz
029     */
030    public final class Throwables {
031    
032      /**
033       * Appends the stack trace of the current thread to the one in the given <code>{@link Throwable}</code>.
034       * @param t the given {@code Throwable}.
035       * @param methodToStartFrom the name of the method used as the starting point of the current thread's stack trace.
036       */
037      public static void appendCurrentThreadStackTraceToThrowable(Throwable t, String methodToStartFrom) {
038        List<StackTraceElement> stackTrace = list(t.getStackTrace());
039        stackTrace.addAll(currentThreadStackTrace(methodToStartFrom));
040        t.setStackTrace(stackTrace.toArray(new StackTraceElement[stackTrace.size()]));
041      }
042    
043      private static List<StackTraceElement> currentThreadStackTrace(String methodToStartFrom) {
044        List<StackTraceElement> filtered = stackTraceInCurrentThread();
045        List<StackTraceElement> toRemove = new ArrayList<StackTraceElement>();
046        for (StackTraceElement e : filtered) {
047          if (methodToStartFrom.equals(e.getMethodName())) break;
048          toRemove.add(e);
049        }
050        filtered.removeAll(toRemove);
051        return filtered;
052      }
053    
054      private static List<StackTraceElement> stackTraceInCurrentThread() {
055        return list(StackTraces.instance().stackTraceInCurrentThread());
056      }
057    
058      private Throwables() {}
059    }