/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.vertical.adminweb;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.Hashtable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.enonic.esl.xml.XMLTool;
import com.enonic.cms.core.xslt.admin.AdminXsltProcessorFactory;
import com.enonic.cms.core.xslt.admin.AdminXsltProcessorHelper;
public class ErrorPageServlet
implements Controller
{
private AdminXsltProcessorFactory xsltProcessorFactory;
private String adminEmail;
public static interface Error
extends Serializable
{
Document toDoc();
}
public final static class ThrowableError
implements Error
{
private Throwable t;
public ThrowableError( Throwable t )
{
this.t = t;
}
public Document toDoc()
{
Document doc = XMLTool.createDocument( "error" );
return ThrowableUtil.throwableToDoc( doc.getDocumentElement(), t );
}
}
public final static class MessageError
implements Error
{
private Object message;
public MessageError( Object message )
{
this.message = message;
}
public Document toDoc()
{
Document doc = XMLTool.createDocument( "error" );
Element root = doc.getDocumentElement();
if ( message != null )
{
XMLTool.createElement( doc, root, "message", message.toString() );
}
else
{
XMLTool.createElement( doc, root, "message" );
}
return doc;
}
}
public final static class TypeError
implements Error
{
private Object type;
private Object message;
public TypeError( Object type, Object message )
{
this.type = type;
this.message = message;
}
public Document toDoc()
{
String fullMessage = type + ": " + message;
Document doc = XMLTool.createDocument( "error" );
Element root = doc.getDocumentElement();
XMLTool.createElement( doc, root, "message", fullMessage );
return doc;
}
}
public final static class CodeError
implements Error
{
private Object code;
private Object message;
public CodeError( Object code, Object message )
{
this.code = code;
this.message = message;
}
public Document toDoc()
{
String fullMessage = code + ": " + message;
Document doc = XMLTool.createDocument( "error" );
Element root = doc.getDocumentElement();
XMLTool.createElement( doc, root, "message", fullMessage );
return doc;
}
}
public ModelAndView handleRequest( HttpServletRequest request, HttpServletResponse response )
throws Exception
{
performTask( request, response );
return null;
}
/**
* Process incoming requests for information
*
* @param request Object that encapsulates the request to the servlet
* @param response Object that encapsulates the response from the servlet
*/
public void performTask( HttpServletRequest request, HttpServletResponse response )
{
HttpSession session = request.getSession( true );
Source xslSource = AdminStore.getStylesheet( session, "error_display.xsl" );
response.setContentType( "text/html;charset=UTF-8" );
// First check if we are used as standard error page for servlet container
Object codeObj, messageObj, typeObj, exceptionObj;
codeObj = request.getAttribute( "javax.servlet.error.status_code" );
messageObj = request.getAttribute( "javax.servlet.error.message" );
typeObj = request.getAttribute( "javax.servlet.error.exception_type" );
exceptionObj = request.getAttribute( "javax.servlet.error.exception" );
Error error;
if ( exceptionObj != null )
{
Throwable t = (Throwable) exceptionObj;
error = new ThrowableError( t );
session.setAttribute( "com.enonic.vertical.error", error );
}
else if ( typeObj != null )
{
error = new TypeError( typeObj, messageObj );
session.setAttribute( "com.enonic.vertical.error", error );
}
else if ( codeObj != null )
{
error = new CodeError( codeObj, messageObj );
session.setAttribute( "com.enonic.vertical.error", error );
}
else
{
error = (Error) session.getAttribute( "com.enonic.vertical.error" );
if ( error == null )
{
error = new MessageError( "No message or throwable given!" );
}
}
DOMSource xmlSource = new DOMSource( error.toDoc() );
Hashtable parameters = new Hashtable();
String showDetails = (String) request.getParameter( "show_details" );
if ( showDetails != null && showDetails.length() > 0 )
{
parameters.put( "show_details", showDetails );
}
else
{
parameters.put( "show_details", "false" );
}
if ( adminEmail != null )
{
parameters.put( "admin_email", adminEmail );
}
try
{
PrintWriter out = response.getWriter();
out.print( transformXML( xmlSource, xslSource, parameters ) );
out.close();
}
catch ( Exception e )
{
String message = "Failed to transform & print output";
VerticalAdminLogger.errorAdmin( message, e );
}
}
public String transformXML( Source xmlSource, Source xslSource, Hashtable parameters )
{
return new AdminXsltProcessorHelper( this.xsltProcessorFactory ).stylesheet( xslSource, null ).input( xmlSource ).params( parameters ).process();
}
@Value("${cms.admin.email}")
public void setAdminEmail( final String adminEmail )
{
this.adminEmail = adminEmail;
}
@Autowired
public void setXsltProcessorFactory( final AdminXsltProcessorFactory xsltProcessorFactory )
{
this.xsltProcessorFactory = xsltProcessorFactory;
}
}