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