001    // Copyright 2008, 2009, 2010, 2011 The Apache Software Foundation
002    //
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.
014    
015    package org.apache.tapestry5.corelib.components;
016    
017    import java.util.List;
018    
019    import org.apache.tapestry5.annotations.Environmental;
020    import org.apache.tapestry5.annotations.Import;
021    import org.apache.tapestry5.annotations.Parameter;
022    import org.apache.tapestry5.annotations.Property;
023    import org.apache.tapestry5.ioc.annotations.Inject;
024    import org.apache.tapestry5.ioc.annotations.Primary;
025    import org.apache.tapestry5.ioc.services.ExceptionAnalysis;
026    import org.apache.tapestry5.ioc.services.ExceptionAnalyzer;
027    import org.apache.tapestry5.ioc.services.ExceptionInfo;
028    import org.apache.tapestry5.services.StackTraceElementAnalyzer;
029    import org.apache.tapestry5.services.StackTraceElementClassConstants;
030    import org.apache.tapestry5.services.javascript.JavaScriptSupport;
031    
032    /**
033     * Integral part of the default {@link org.apache.tapestry5.corelib.pages.ExceptionReport} page used to break apart and
034     * display the properties of the exception.
035     * 
036     * @see org.apache.tapestry5.ioc.services.ExceptionAnalyzer
037     * @tapestrydoc
038     */
039    @Import(library = "exceptiondisplay.js")
040    public class ExceptionDisplay
041    {
042        /**
043         * Exception to report.
044         */
045        @Parameter(required = true, allowNull = false)
046        private Throwable exception;
047    
048        @Inject
049        private ExceptionAnalyzer analyzer;
050    
051        @Property
052        private ExceptionInfo info;
053    
054        @Property
055        private String propertyName;
056    
057        @Property
058        private StackTraceElement frame;
059    
060        @Property
061        private List<ExceptionInfo> stack;
062    
063        @Environmental
064        private JavaScriptSupport jsSupport;
065    
066        @Property
067        private String toggleId;
068    
069        private boolean sawDoFilter;
070    
071        @Inject
072        @Primary
073        private StackTraceElementAnalyzer frameAnalyzer;
074    
075        void setupRender()
076        {
077            ExceptionAnalysis analysis = analyzer.analyze(exception);
078    
079            stack = analysis.getExceptionInfos();
080    
081            toggleId = jsSupport.allocateClientId("toggleStack");
082        }
083    
084        public boolean getShowPropertyList()
085        {
086            // True if either is non-empty
087    
088            return !(info.getPropertyNames().isEmpty() && info.getStackTrace().isEmpty());
089        }
090    
091        public Object getPropertyValue()
092        {
093            return info.getProperty(propertyName);
094        }
095    
096        public String getFrameClass()
097        {
098            if (sawDoFilter)
099                return StackTraceElementClassConstants.OMITTED;
100    
101            String result = frameAnalyzer.classForFrame(frame);
102    
103            sawDoFilter |= frame.getMethodName().equals("doFilter");
104    
105            return result;
106        }
107    
108        void afterRender()
109        {
110            jsSupport.addScript("Tapestry.stackFrameToggle('%s');", toggleId);
111        }
112    }