    001// Copyright 2008-2013 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 org.apache.tapestry5.annotations.Import;
    018import org.apache.tapestry5.annotations.Parameter;
    019import org.apache.tapestry5.annotations.Property;
    020import org.apache.tapestry5.ioc.annotations.Inject;
    021import org.apache.tapestry5.ioc.annotations.Primary;
    022import org.apache.tapestry5.ioc.services.ExceptionAnalysis;
    023import org.apache.tapestry5.ioc.services.ExceptionAnalyzer;
    024import org.apache.tapestry5.ioc.services.ExceptionInfo;
    025import org.apache.tapestry5.services.StackTraceElementAnalyzer;
    026import org.apache.tapestry5.services.StackTraceElementClassConstants;
    027
    028import java.util.List;
    029
    030/**
    031 * Integral part of the default {@link org.apache.tapestry5.corelib.pages.ExceptionReport} page used to break apart and
    032 * display the properties of the exception.
    033 *
    034 * @tapestrydoc
    035 * @see org.apache.tapestry5.ioc.services.ExceptionAnalyzer
    036 */
    037@Import(stylesheet = "ExceptionDisplay.css", module = "t5/core/exception-display")
    038public class ExceptionDisplay
    039{
    040    /**
    041     * Exception to report.
    042     */
    043    @Parameter(required = true, allowNull = false)
    044    private Throwable exception;
    045
    046    @Inject
    047    private ExceptionAnalyzer analyzer;
    048
    049    @Property
    050    private ExceptionInfo info;
    051
    052    @Property
    053    private String propertyName;
    054
    055    @Property
    056    private StackTraceElement frame;
    057
    058    @Property
    059    private List<ExceptionInfo> stack;
    060
    061    private boolean sawDoFilter;
    062
    063    @Inject
    064    @Primary
    065    private StackTraceElementAnalyzer frameAnalyzer;
    066
    067    void setupRender()
    068    {
    069        ExceptionAnalysis analysis = analyzer.analyze(exception);
    070
    071        stack = analysis.getExceptionInfos();
    072    }
    073
    074    public Object getPropertyValue()
    075    {
    076        return info.getProperty(propertyName);
    077    }
    078
    079    public String getFrameClass()
    080    {
    081        if (sawDoFilter)
    082        {
    083            return StackTraceElementClassConstants.OMITTED;
    084        }
    085
    086        String result = frameAnalyzer.classForFrame(frame);
    087
    088        sawDoFilter |= frame.getMethodName().equals("doFilter");
    089
    090        return result;
    091    }
    092
    093    public Object getLineNumberForFrame()
    094    {
    095        if (frame.getLineNumber() < 1)
    096        {
    097            return "";
    098        }
    099
    100        return frame.getLineNumber();
    101    }
    102
    103    public String getFramePackageName()
    104    {
    105        return splitClass()[0];
    106    }
    107
    108    public String getFrameClassName()
    109    {
    110        return splitClass()[1];
    111    }
    112
    113    private String[] splitClass()
    114    {
    115        String name = frame.getClassName();
    116
    117        int dotx = name.lastIndexOf('.');
    118
    119        // For generated classes in root package:
    120        if (dotx < 0)
    121        {
    122            return new String[]{"", name};
    123        }
    124
    125        // For normal classes:
    126
    127        return new String[]{
    128                name.substring(0, dotx),
    129                name.substring(dotx)
    130        };
    131    }
    132}
    133