Package com.pugh.sockso.web

Source Code of com.pugh.sockso.web.ServerThread

package com.pugh.sockso.web;

import com.pugh.sockso.Constants;
import com.pugh.sockso.Properties;
import com.pugh.sockso.db.Database;
import com.pugh.sockso.resources.Locale;
import com.pugh.sockso.resources.LocaleFactory;
import com.pugh.sockso.resources.Resources;
import com.pugh.sockso.web.action.Errorer;
import com.pugh.sockso.web.action.WebAction;
import com.pugh.sockso.web.log.DbRequestLogger;
import com.pugh.sockso.web.log.RequestLogger;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.net.Socket;
import java.net.SocketException;

import org.apache.log4j.Logger;

import com.google.inject.Inject;

public class ServerThread extends Thread {

    private static final Logger log = Logger.getLogger( ServerThread.class );

    private final Server sv;
    private final Database db;
    private final Properties p;
    private final Resources r;
    private final Dispatcher dispatcher;
    private final LocaleFactory localeFactory;

    private Socket client;
   
    /**
     *  Creates a new instance of ServerThread
     *
     *  @param server the server this thread is attached to
     *  @param db the database connection
     *  @param p app properties
     *  @param r app resources
     *
     */
   
    @Inject
    public ServerThread( final Server server, final Database db, final Properties p,
                         final Resources r, final Dispatcher dispatcher, final LocaleFactory localeFactory ) {

        this.sv = server;
        this.db = db;
        this.p = p;
        this.r = r;
        this.dispatcher = dispatcher;
        this.localeFactory = localeFactory;
               
    }
   
    /**
     *  Sets the client socket to use to communicate with the caller
     *
     *  @param client
     *
     */
   
    public void setClientSocket( final Socket client ) {
       
        this.client = client;
       
    }
   
    /**
     *  the service, handles the request
     *
     */
   
    @Override
    public void run() {

        Response res = null;
        Request req = null;
        User user = null;
       
        try {

            req = new HttpRequest( sv );
            req.process( new BufferedInputStream(client.getInputStream()) );

            Locale locale = localeFactory.getLocale( req.getPreferredLangCode() );

            final WebAction action = dispatcher.getAction( req );
            action.setRequest( req );
            action.setLocale( locale );

            if ( action.requiresSession() ) {
                final Session session = new Session( db, req, null );
                user = session.getCurrentUser();
            }

            action.setUser( user );

            res = new HttpResponse(
                new BufferedOutputStream(client.getOutputStream()),
                db, p, locale, user,
                req.getHeader("Accept-Encoding").contains("gzip")
                    // @TODO fix safari gzip bug
                    && !req.getHeader("User-Agent").contains("Safari")
            );

            action.setResponse( res );

            process( action, user, req, locale, res );

        }
       
        // client has probably disconnected, ignore
        catch ( final SocketException e ) {}

        // ignore unknown IE6 behaviour
        catch ( final EmptyRequestException e ) {}
       
        // "handled" exception from Sockso
        catch ( final BadRequestException e ) {
            showException( e, req, res, false );
        }

        // something bad like IO, SQL, etc...
        catch ( final Exception e ) {
            // create our own (exception for the template) but clone the stack trace...
            final BadRequestException exception = new BadRequestException( e.getMessage(), 500 );
            exception.setStackTrace( e.getStackTrace() );
            showException( exception, req, res, true );
        }

        finally {
            // we're done with the request so we can close the
            // connection to the client now.
            try { client.close(); }
            catch ( Exception e ) {}
        }
       
        sv.requestComplete( this );

    }

    /**
     *  Process a request and generate a response
     *
     *  @param action
     *  @param user
     *  @param req
     *  @param locale
     *  @param res
     *
     *  @throws Exception
     *
     */

    protected void process( final WebAction action, final User user, final Request req, final Locale locale, final Response res ) throws Exception {

        if ( p.get(Constants.WWW_LOG_REQUESTS_ENABLED).equals(Properties.YES) ) {
            final RequestLogger logger = new DbRequestLogger( db );
            logger.log( user, client.getInetAddress().getHostAddress(),
                req.getResource(), req.getHeader("User-Agent"),
                req.getHeader("Referer"), req.getHeader("Cookie") );
        }
       
        if ( action == null ) {
            throw new BadRequestException(locale.getString("www.error.unknownRequest"), 400);
        }

        if ( loginRequired(user,action) ) {
            res.redirect( p.getUrl("/user/login"));
        }

        else {
            action.handleRequest();
        }

    }

    /**
     *  Indicates if the user needs to log in before running this action
     *
     *  @param user
     *  @param action
     *
     *  @return
     *
     */

    protected boolean loginRequired( final User user, final WebAction action ) {

        return p.get( Constants.WWW_USERS_REQUIRE_LOGIN ).equals( p.YES )
            && user == null
            && action.requiresLogin();

    }

    /**
     *  Shows an error, and sends the status code in the response
     *
     *  @param e
     *  @param req
     *  @param res
     *  @param showStackTrace
     *
     */
   
    private void showException( final BadRequestException e, final Request req, final Response res, final boolean showStackTrace ) {

        log.error( e.getMessage() );
       
        if ( showStackTrace ) {
            e.printStackTrace();
        }

        final Errorer err = new Errorer( e, showStackTrace );
        err.setRequest( req );
        err.setResponse( res );

        try { err.handleRequest(); }
            catch ( final Exception e2 ) { /* an error showing the error message, ummm.. */ }

    }
   
    /**
     *  tries to shut down the thread cleanly
     *
     */
   
    public void shutdown() {
       
        log.info( "Shutting Down" );
   
        try { finalize(); }
            catch ( Throwable t ) {}
       
    }


}
TOP

Related Classes of com.pugh.sockso.web.ServerThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.