<%@ page import="java.io.PrintWriter,
                 java.io.BufferedReader,
                 java.io.StringReader,
                 com.atlassian.confluence.admin.actions.ViewSystemInfoAction,
                 java.util.*,
                 com.atlassian.core.logging.ThreadLocalErrorCollection,
                 org.apache.log4j.spi.LoggingEvent,
                 com.atlassian.core.logging.DatedLoggingEvent,
                 com.atlassian.confluence.util.GeneralUtil" %>
<%@ page import="java.lang.reflect.InvocationTargetException"%>
<%@ page import="org.apache.velocity.exception.MethodInvocationException"%>
<%@ page import="com.atlassian.plugin.Plugin"%>
<%@ page import="com.atlassian.plugin.PluginInformation"%>
<%@ page import="com.atlassian.confluence.util.PatternLayoutWithStackTrace"%>
<%@ page import="com.atlassian.confluence.user.AuthenticatedUserThreadLocal"%>
<%@ page import="com.atlassian.confluence.util.I18NSupport"%>
<%@ page isErrorPage="true" %>
<% try { %>
<html>
	<head>
	<title>Oops - an error has occurred</title>
    <link rel="stylesheet" href="<%= request.getContextPath() %>/styles/main-action.css" type="text/css" />
    <script language="JavaScript" type="text/javascript" src="<%=request.getContextPath()%>/includes/js/cookieUtils.js"></script>
    <style>
        p { padding: 5px 10px 5px 10px;}
		p.message { padding: 10px 30px 10px 30px; font-weight: bold; font-size: 130%; border-width: 1px; border-style: dashed; border-color: #336699; }
		p.description { padding: 10px 30px 20px 30px; border-width: 0px 0px 1px 0px; border-style: solid; border-color: #336699;}
		p.topped { padding: 5px 10px 5px 0px; margin: 0px 0px 0px 10px; border-width: 1px 0px 0px 0px; border-style: solid; border-color: #003366; }
        span.switch { cursor: pointer; margin-left: 5px; text-decoration: underline; }
        pre {padding: 5px 10px 5px 10px;}
   </style>
   </head>

<body>
<div id="PageContent">
    <table border="0" cellpadding="0" cellspacing="0" width="100%">
        <tr>
        <td class="logoSpaceLink"><a href="<%= request.getContextPath() %>/">CONFLUENCE</a></td>
        </tr>
    </table>

    <table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%">
        <tr>
            <td valign="top" class="pagebody">
				<div class="pageheader" style="margin: 0 10px 0 10px">
					<span class="pagetitle">System Error</span>
				</div>

        <div class="functionbox" style="margin: 10px; padding: 10px;">
        A system error has occurred - our apologies!
        <p>
        Please create a support issue on our <b>support system</b> at <a href="<%= I18NSupport.getText("url.support")%>"><%= I18NSupport.getText("url.support")%></a> with the following information:
        <ol>
        <li>a description of your problem and what you were doing at the time it occurred
        <li>cut &amp; paste the error and system information found below
        <li>attach the application server log file (if possible).
        </ol>
        </p>


        We will respond as promptly as possible.<br/>Thank you!
        </div>
        <%
            ViewSystemInfoAction vsi = new ViewSystemInfoAction(pageContext.getServletContext());
            Map sysinfo = vsi.getProps();
            Map jvmstats = vsi.getJVMstats();
            Map buildstats = vsi.getBuildStats();

            // orion does not support the exception object.
            boolean isOrion = "Orion".equals(vsi.getAppServer());
        %>

        <p>
        <b>Cause:</b><br/>

        <%
            if (isOrion)
            {
                String ex = (String) request.getAttribute("javax.servlet.error.message");
                //get the first line of the error message for the "cause:"

                String line = "";
                if (ex != null)
                    line = new BufferedReader(new StringReader(ex)).readLine();
                else
                    line = "No exception";

        %>
        <%= line %>
        </p>
        <p>
        <b>Stack Trace:</b> <span class="switch" id="stacktrace-switch" onclick="toggle('stacktrace')">[hide]</span>

        <pre id="stacktrace"><%= ex %></pre>
        <%
            }
            else
            {
                if (exception != null)
                {
                    %>
                    <table>
                    <%
                    Throwable throwable = exception;
                     String causedBy = "";
                    while (throwable != null)
                    { %>
                        <tr><td><%= causedBy + throwable + "<br/>&nbsp;at " + throwable.getStackTrace()[0] %></td></tr>
                    <%
                        causedBy = "caused by: ";
                        if (throwable instanceof InvocationTargetException)
                        {
                            throwable = ((InvocationTargetException)throwable).getTargetException();
                        }
                        else if (throwable instanceof MethodInvocationException)
                        {
                            throwable = ((MethodInvocationException)throwable).getWrappedThrowable();
                        }
                        else if (throwable instanceof ServletException)
                        {
                            throwable = ((ServletException)throwable).getRootCause();
                        }
                        else
                        {
                            throwable = throwable.getCause();
                        }
                    }
                     %>
                    </table>
                    <%
        %>

        <p>
        <b>Stack Trace:</b> <span class="switch" id="stacktrace-switch" onclick="toggle('stacktrace')">[hide]</span>

        <pre id="stacktrace"><%
                    StringBuffer sb = new StringBuffer();
                    PatternLayoutWithStackTrace.appendStackTrace(sb, exception);
                    out.print(sb.toString());
                %></pre>
        <%
                }
            }
        %>
        <p><b>Referer URL:</b> <%= request.getHeader("Referer") != null ? request.getHeader("Referer") : "Unknown" %></p>

        <p>
        <b>Build Information:</b><br/>
        <%
            for (Iterator k = buildstats.keySet().iterator(); k.hasNext();)
            {
                String key = (String) k.next();
                String value = (String) buildstats.get(key);
                out.println(key + ": " + value + "<br/>");
            }
        %>
        </p>
        <p>
        <b>Server Information:</b><br/>
            Application Server: <%= application.getServerInfo() %><br>
            Servlet Version: <%= application.getMajorVersion() %>.<%= application.getMinorVersion() %><br>
            Database Dialect: <%= vsi.getDatabaseDialect() %><br>
            Database Driver Name: <%= vsi.getDatabaseDriverName() %><br>
            Database Driver Version: <%= vsi.getDatabaseDriverVersion() %><br>
        </p>
        <p>
        <b>Memory Information:</b><br/>
        <%
            for (Iterator j = jvmstats.keySet().iterator(); j.hasNext();)
            {
                String key = (String) j.next();
                String value = (String) jvmstats.get(key);
                out.println(key + ": " + value + " MB<br/>");
            }
        %>
        </p>
        <p>
        <b>System Information:</b><br/>
        <%
            for (Iterator i = sysinfo.keySet().iterator(); i.hasNext();)
            {
                String key = (String) i.next();
                String value = (String) sysinfo.get(key);
                out.println(key + ": " + value + "<br/>");
            }
        %>
        </p>

        <p>
            <b>Enabled Plugins:</b><br />
            <%
                try
                {
                List enabledPlugins = vsi.getEnabledPlugins();

                if (enabledPlugins == null)
                {
                    out.println("There was an issue retrieving the plugin manager from the Spring context. Please check your logs." + "<br />");
                }
                else
                {
                    for (Iterator l = enabledPlugins.iterator(); l.hasNext();)
                    {
                        Plugin plugin = (Plugin) l.next();
                        PluginInformation pluginInfo = plugin.getPluginInformation();

                        String pluginName = plugin.getName();
                        String pluginKey = plugin.getKey();
                        String pluginVersion;

                        if (pluginInfo == null)
                        {
                            pluginVersion = "N/A";
                        }
                        else
                        {
                            pluginVersion = pluginInfo.getVersion();

                            // If version isn't defined, put something sane in
                            if (pluginVersion == null)
                                pluginVersion = "N/A";
                        }

                        out.println(pluginName + " (" + pluginKey + ", Version: " + pluginVersion + ")<br />");
                    }
                }
                }
                catch (Exception e)
                {
                    out.println("Couldn't report plugins:" + e);
                }
            %>
        </p>

        <div style="font-size: 14px; margin: 0 0 0 10px; font-weight: bold;">Request</div>
        <p>
        <%
            try {
        %>
            <b>Information:</b><br>
            URL: <%= request.getRequestURL() %><br>
            - Scheme: <%= request.getScheme() %><br>
            - Server: <%= request.getServerName() %><br>
            - Port: <%= request.getServerPort() %><br>
            - URI: <%= request.getRequestURI() %><br>
            - - Context Path: <%= request.getContextPath() %><br>
            - - Servlet Path: <%= request.getServletPath() %><br>
            - - Path Info: <%= request.getPathInfo() %><br>
            - - Query String: <%= request.getQueryString() %><br>
        </p>
        <p>
            <b>Attributes:</b><br>
            <%
                Enumeration attributeNames = request.getAttributeNames();
                while (attributeNames.hasMoreElements())
                {
                    String name = (String) attributeNames.nextElement();
                    %>
                    - <%= name %> : <%= request.getAttribute(name) %><br>
                    <%
                }
            %>
        </p>
        <p>
            <b>Parameters:</b><br>
            <%
                for (Enumeration paramNames = request.getParameterNames(); paramNames.hasMoreElements();)
                {
                    String paramName = (String) paramNames.nextElement();
                    String[] paramValues = request.getParameterValues(paramName);

                    %>
                    - <%= GeneralUtil.htmlEncode(paramName) %> =

                    <%
                    for (int i = 0; i < paramValues.length; i++)
                    {
                        String paramValue = paramValues[i];
                        out.print(GeneralUtil.htmlEncode(paramValue));
                        if (i < paramValues.length - 1)
                            out.println(", ");
                    }
                    %>
                        <br>
                    <%
                }
            %>
            <b>Confluence User:</b><br>
            - <%= GeneralUtil.htmlEncode(AuthenticatedUserThreadLocal.getUsername() == null ? "anonymous" : AuthenticatedUserThreadLocal.getUsername()) %>

        <%
            }
            catch (Throwable t)
            {
                out.println("Error rendering logging information - uh oh.");
                t.printStackTrace(new PrintWriter(out));
            }
        %>
        </p>

<style>
.logStatement {
font-weight: bold;
padding: 4px;
margin: 4px;
border: 1px #bbb solid;
}
.logThrowable {
font-weight: normal;
padding: 4px 10px 4px 4px;
}
</style>
        <p>
        <b>Logging:</b><br>
        <%
            try
            {
            List list = ThreadLocalErrorCollection.getList();
            %>
                <b><%= list.size() %></b> log statements generated by this request<%= list.size() > 0 ? ":" : "." %>
                <br>
            <%
            for (Iterator iterator = list.iterator(); iterator.hasNext();)
            {
                Object o = iterator.next();

                if (o instanceof DatedLoggingEvent)
                {
                    DatedLoggingEvent dle = (DatedLoggingEvent) o;
                    LoggingEvent loggingEvent = dle.getEvent();
                    Date date = dle.getDate();
                %>
                <div class="logStatement">
                <font color="darkred">[<%= loggingEvent.getLevel() %>]</font>
                <font color="darkblue"><%= date.toString() %></font>
                [<%= loggingEvent.getLoggerName() %>]
                <%= loggingEvent.getRenderedMessage() %>
                <br>
                <% if (loggingEvent.getThrowableInformation() != null) { %>
                    <div class="logThrowable">
                        <b>Throwable:</b><br>
                        <%
                            for (int i = 0; i < loggingEvent.getThrowableStrRep().length && i < 20; i++)
                            {
                                String s = loggingEvent.getThrowableStrRep()[i];
                                out.println("" + s + "<br>");
                            }
                        %>
                    </div>
                <% } // if %>
                </div>
                <%}
                else
                { %>
                   <%= o.getClass() %>: <%= o %>
                <% }
            } // for
            } // try
            catch (Throwable t)
            {
                out.println("<div class='error'><div class='errorMessage'  style='font-weight: bold;'>Error rendering logging information - uh oh.</div><pre>");
                t.printStackTrace(new PrintWriter(out));
                out.println("</pre></div>");
            }
        %>
        </p>

        </td>
        </tr>
    </table>
</div>
</body>
</html>
<%
    }
    finally
    {
    out.flush();
    }
%>