001    /*
002     * Copyright (C) 2006-2007 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.codehaus.gmaven.runtime.support;
018    
019    import org.codehaus.gmaven.feature.Configuration;
020    import org.codehaus.gmaven.feature.Feature;
021    import org.codehaus.gmaven.feature.support.ComponentSupport;
022    import org.codehaus.gmaven.runtime.TraceSanitizer;
023    
024    import java.io.PrintWriter;
025    import java.util.ArrayList;
026    import java.util.List;
027    
028    //
029    // NOTE: Based on from org.codehaus.groovy.runtime.StackTraceUtils.
030    //
031    
032    /**
033     * Provides a default stack trace sanitizer, should work with most versions of Groovy.
034     *
035     * @version $Id: TraceSanitizerSupport.java 18 2009-07-16 09:39:40Z user57 $
036     * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
037     */
038    public class TraceSanitizerSupport
039        extends ComponentSupport
040        implements TraceSanitizer
041    {
042        public static final String[] FILTERED_PREFIXES = {
043            "groovy.",
044            "org.codehaus.groovy.",
045            "java.",
046            "javax.",
047            "sun.",
048            "gjdk.groovy.",
049        };
050    
051        public TraceSanitizerSupport(final Feature feature, final Configuration config) {
052            super(feature, config);
053        }
054    
055        public TraceSanitizerSupport(final Feature feature) {
056            super(feature);
057        }
058    
059        public boolean filter(final String className) {
060            assert className != null;
061    
062            for (int i = 0; i < FILTERED_PREFIXES.length; i++) {
063                if (className.startsWith(FILTERED_PREFIXES[i])) {
064                    return true;
065                }
066            }
067    
068            return false;
069        }
070    
071        public boolean filter(final Class type) {
072            assert type != null;
073    
074            return filter(type.getName());
075        }
076    
077        public Throwable sanitize(final Throwable t, final boolean deep) {
078            assert t != null;
079    
080            if (deep) {
081                Throwable current = t;
082    
083                while (current.getCause() != null) {
084                    current = sanitize(current.getCause(), false);
085                }
086            }
087    
088            StackTraceElement[] trace = t.getStackTrace();
089    
090            List list = new ArrayList();
091    
092            for (int i = 0; i < trace.length; i++) {
093                if (!filter(trace[i].getClassName())) {
094                    list.add(trace[i]);
095                }
096            }
097    
098            t.setStackTrace((StackTraceElement[]) list.toArray(new StackTraceElement[list.size()]));
099    
100            return t;
101        }
102    
103        public Throwable sanitize(final Throwable t) {
104            return sanitize(t, false);
105        }
106    
107        public void print(final Throwable t, final PrintWriter out, final boolean deep) {
108            assert t != null;
109            assert out != null;
110    
111            StackTraceElement[] trace = sanitize(t, deep).getStackTrace();
112    
113            for (int i = 0; i < trace.length; i++) {
114                synchronized (out) {
115                    //
116                    // TODO: See if we can just use the toString()... why this muck?
117                    //
118    
119                    out.print("at ");
120                    out.print(trace[i].getClassName());
121                    out.print("(");
122                    out.print(trace[i].getMethodName());
123                    out.print(":");
124                    out.print(trace[i].getLineNumber());
125                    out.println(")");
126                }
127            }
128        }
129    
130        public void print(final Throwable t, final PrintWriter out) {
131            print(t, out, false);
132        }
133    
134        public void print(final Throwable t) {
135            print(t, new PrintWriter(System.err, true));
136        }
137    }