package com.dodo.blog.servlet;
import com.dodo.blog.RequestCycle;
import com.dodo.blog.WebApplication;
import com.dodo.blog.model.Account;
import com.dodo.blog.model.Role;
import com.dodo.blog.ui.ajax.AjaxListenerHelper;
import com.dodo.blog.ui.ajax.IAjaxRequestHandler;
import com.dodo.blog.ui.authorization.Authorized;
import com.dodo.blog.ui.page.ErrorPage;
import com.dodo.blog.ui.page.Page;
import com.google.inject.Injector;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.logging.Logger;
/**
* @author <a href="mailto:pohorelec@comvai.com">Jozef Pohorelec</a>
*/
public class ApplicationFilter
implements Filter
{
private Logger log = Logger.getLogger( ApplicationFilter.class.getName() );
// TODO: make as singleton and inject by guice
private static final WebApplication webApplication = WebApplication.get();
private FilterConfig config;
@Override
public void init( FilterConfig filterConfig ) throws ServletException
{
this.config = filterConfig;
}
@Override
@SuppressWarnings( value = "unchecked" )
public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain )
throws IOException, ServletException
{
HttpServletRequest httpRequest = ( HttpServletRequest ) request;
HttpServletResponse httpResponse = ( HttpServletResponse ) response;
// set request cycle
RequestCycle.set( httpRequest, httpResponse, webApplication, config );
// get path
String path = httpRequest.getServletPath();
Class pageClass = webApplication.getPageClassByPath( path );
if ( pageClass == null )
{
chain.doFilter( request, response );
return;
}
response.setContentType( "text/html" );
response.setCharacterEncoding( "UTF-8" );
try
{
// check authorization
if ( !isAuthorized( pageClass ) )
{
Injector injector = RequestCycle.get().getInjector();
Page page = injector.getInstance( WebApplication.get().getUnauthorizedPage() );
response.getWriter().write( page.render() );
return;
}
// handle ajax calls
if ( AjaxListenerHelper.isAjax() )
{
String paramHandler = request.getParameter( IAjaxRequestHandler.PARAM_AJAX_HANDLER );
if ( paramHandler != null )
{
IAjaxRequestHandler handler = ( IAjaxRequestHandler ) Class.forName( paramHandler ).newInstance();
handler.handle();
return;
}
}
// regular page calls
Injector injector = RequestCycle.get().getInjector();
Page page = ( Page ) injector.getInstance( pageClass );
response.getWriter().write( page.render() );
}
catch ( Exception e )
{
processError( e, path, httpResponse );
}
}
private void processError( Exception e, String path, HttpServletResponse httpResponse )
{
StringBuilder sb = new StringBuilder();
sb.append( "Error occurred during creating page fot path[" ).append( path ).append( "]: " ).append( e ).append( ", cause: " ).append( e.getCause() ).append( "\n" );
StringWriter sw = new StringWriter();
e.printStackTrace( new PrintWriter( sw ) );
log.severe( sw.toString() );
try
{
ErrorPage errorPage = RequestCycle.get().getWebApplication().getErrorPage().newInstance();
errorPage.setError( e );
httpResponse.getWriter().write( errorPage.render() );
httpResponse.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
}
catch ( Exception e1 )
{
log.severe( "Error occurred during creating error page:" + e1 );
}
}
private boolean isAuthorized( Class clazz )
{
Authorized authorizedRoles = ( Authorized ) clazz.getAnnotation( Authorized.class );
boolean isAuthorized = false;
if ( authorizedRoles != null )
{
Account account = WebApplication.get().getLoggedInAccount();
if ( account != null )
{
for ( Role role : authorizedRoles.roles() )
{
if ( account.getRole() == role )
{
isAuthorized = true;
break;
}
}
}
}
else
{
isAuthorized = true;
}
return isAuthorized;
}
@Override
public void destroy()
{
}
}