    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    }