    001    // Copyright 2006, 2007, 2008, 2009 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.pages;
    016
    017    import org.apache.tapestry5.SymbolConstants;
    018    import org.apache.tapestry5.annotations.ContentType;
    019    import org.apache.tapestry5.annotations.Property;
    020    import org.apache.tapestry5.ioc.annotations.Inject;
    021    import org.apache.tapestry5.ioc.annotations.Symbol;
    022    import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    023    import org.apache.tapestry5.services.ExceptionReporter;
    024    import org.apache.tapestry5.services.Request;
    025    import org.apache.tapestry5.services.Session;
    026
    027    import java.util.List;
    028    import java.util.regex.Pattern;
    029
    030    /**
    031     * Responsible for reporting runtime exceptions. This page is quite verbose and is usually overridden in a production
    032     * application. When {@link org.apache.tapestry5.SymbolConstants#PRODUCTION_MODE} is "true", it is very abbreviated.
    033     *
    034     * @see org.apache.tapestry5.corelib.components.ExceptionDisplay
    035     */
    036    @ContentType("text/html")
    037    public class ExceptionReport implements ExceptionReporter
    038    {
    039        private static final String PATH_SEPARATOR_PROPERTY = "path.separator";
    040
    041        // Match anything ending in .(something?)path.
    042
    043        private static final Pattern PATH_RECOGNIZER = Pattern.compile("\\..*path$");
    044
    045        @Property
    046        private String attributeName;
    047
    048        @Inject
    049        @Property
    050        private Request request;
    051
    052        @Inject
    053        @Symbol(SymbolConstants.PRODUCTION_MODE)
    054        @Property(write = false)
    055        private boolean productionMode;
    056
    057        @Inject
    058        @Symbol(SymbolConstants.TAPESTRY_VERSION)
    059        @Property(write = false)
    060        private String tapestryVersion;
    061
    062        @Inject
    063        @Symbol(SymbolConstants.APPLICATION_VERSION)
    064        @Property(write = false)
    065        private String applicationVersion;
    066
    067        @Property(write = false)
    068        private Throwable rootException;
    069
    070        @Property
    071        private String propertyName;
    072
    073        private final String pathSeparator = System.getProperty(PATH_SEPARATOR_PROPERTY);
    074
    075        public void reportException(Throwable exception)
    076        {
    077            rootException = exception;
    078        }
    079
    080        public boolean getHasSession()
    081        {
    082            return request.getSession(false) != null;
    083        }
    084
    085        public Session getSession()
    086        {
    087            return request.getSession(false);
    088        }
    089
    090        public Object getAttributeValue()
    091        {
    092            return getSession().getAttribute(attributeName);
    093        }
    094
    095        /**
    096         * Returns a <em>sorted</em> list of system property names.
    097         */
    098        public List<String> getSystemProperties()
    099        {
    100            return InternalUtils.sortedKeys(System.getProperties());
    101        }
    102
    103        public String getPropertyValue()
    104        {
    105            return System.getProperty(propertyName);
    106        }
    107
    108        public boolean isComplexProperty()
    109        {
    110            return PATH_RECOGNIZER.matcher(propertyName).find() && getPropertyValue().contains(pathSeparator);
    111        }
    112
    113        public String[] getComplexPropertyValue()
    114        {
    115            // Neither : nor ; is a regexp character.
    116
    117            return getPropertyValue().split(pathSeparator);
    118        }
    119    }