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
015package org.apache.tapestry5.corelib.components;
016
017import java.util.List;
018
019import org.apache.tapestry5.annotations.Environmental;
020import org.apache.tapestry5.annotations.Import;
021import org.apache.tapestry5.annotations.Parameter;
022import org.apache.tapestry5.annotations.Property;
023import org.apache.tapestry5.ioc.annotations.Inject;
024import org.apache.tapestry5.ioc.annotations.Primary;
025import org.apache.tapestry5.ioc.services.ExceptionAnalysis;
026import org.apache.tapestry5.ioc.services.ExceptionAnalyzer;
027import org.apache.tapestry5.ioc.services.ExceptionInfo;
028import org.apache.tapestry5.services.StackTraceElementAnalyzer;
029import org.apache.tapestry5.services.StackTraceElementClassConstants;
030import 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")
040public 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}