package net.frenopatico.citadels.app;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.Principal;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.Synchronized;
import lombok.extern.java.Log;
import net.frenopatico.citadels.controller.IPlayersService;
import net.frenopatico.citadels.enums.LoginStatus;
import net.frenopatico.citadels.view.accessors.Logs;
import net.frenopatico.citadels.view.windows.LoginWindow;
import net.frenopatico.citadels.view.windows.MainWindow;
import com.vaadin.Application;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.gwt.server.HttpServletRequestListener;
/**
* Main application in the game.
*
* @author eduardo.ramirez.ronco@gmail.com
*/
@Log
public class CitadelsApplication extends Application implements HttpServletRequestListener {
private static final long serialVersionUID = -3619396575651214788L;
private static final String AJAX_PREFIX = "UIDL";
private static MainWindow mainWin;
private static LoginWindow loginWin;
private static IPlayersService playersSrv;
private LoginStatus loginStatus;
/**
* Wire and initialize the application.
*
*/
@Inject
public CitadelsApplication( final MainWindow mainWindow, final LoginWindow loginWindow, final IPlayersService playersService ) {
mainWin = mainWindow;
loginWin = loginWindow;
playersSrv = playersService;
setMainWindow( mainWin );
addWindow( loginWin );
}
@Override
public void init() {
// UI initialization is deferred because we need to check the login status.
}
public final void onRequestStart( final HttpServletRequest request, final HttpServletResponse response ) {
final String pathInfo = request.getPathInfo();
// We don't manage the UI on AJAX requests.
if( !pathInfo.contains( AJAX_PREFIX ) ) {
final Principal userPrincipal = request.getUserPrincipal();
final LoginStatus newStatus = checkLoginStatus( userPrincipal );
// If this is the first access or there's a change in the login status we repaint the UI.
if( loginStatus == null || newStatus != this.loginStatus ) {
loginStatus = newStatus;
final String requestURI = request.getRequestURI();
final StringBuffer requestURL = request.getRequestURL();
buildUI( requestURI, requestURL );
}
}
}
public void onRequestEnd( final HttpServletRequest request, final HttpServletResponse response ) {
// There's nothing to do.
}
/**
* Build the UI depending on the Login status.
*
* @param requestURI Main URI for the application.
* @param requestURL Request URL to construct.
*/
@Synchronized
private void buildUI( final String requestURI, final StringBuffer requestURL ) {
log.info( Logs.get( "app.buildiu.init" ) );
switch( loginStatus ) {
case Login:
mainWin.initialize( requestURI );
break;
case Logout:
case Unlogged:
if( !loginWin.isInitialized() ) {
loginWin.initialize( requestURI );
}
URI reportURI;
try {
reportURI = loginWin.getURL().toURI();
URL windowURL = new URI( reportURI.getScheme(), reportURI.getUserInfo(), reportURI.getHost(), reportURI.getPort(), reportURI.getPath(), "", null ).toURL();
mainWin.open( new ExternalResource( windowURL ) );
} catch( URISyntaxException e ) {
log.severe( Logs.get( "app.buildui.uri.syntax" ) );
} catch( MalformedURLException e ) {
log.severe( Logs.get( "app.buildui.uri.malformed" ) );
}
break;
default:
break;
}
}
/**
* Checks the login status of the user.
*
* @param userPrincipal Main user logged in the application.
* @return Login status of the user.
*/
private LoginStatus checkLoginStatus( final Principal userPrincipal ) {
LoginStatus status;
final Object user = getUser();
if( userPrincipal == null && user == null ) {
status = LoginStatus.Unlogged;
} else if( userPrincipal == null && user != null ) {
setUser( null );
status = LoginStatus.Logout;
} else if( userPrincipal != null && user == null ) {
setUser( userPrincipal.getName() );
status = LoginStatus.Login;
} else {
status = LoginStatus.Loggedin;
}
return status;
}
}