package com.pugh.sockso.web.action;
import com.pugh.sockso.Constants;
import com.pugh.sockso.Properties;
import com.pugh.sockso.cache.ObjectCache;
import com.pugh.sockso.templates.api.TException;
import com.pugh.sockso.web.BadRequestException;
import com.pugh.sockso.web.Request;
import com.pugh.sockso.web.action.api.AlbumAction;
import com.pugh.sockso.web.action.api.AlbumTracksAction;
import com.pugh.sockso.web.action.api.AlbumsAction;
import com.pugh.sockso.web.action.api.ApiAction;
import com.pugh.sockso.web.action.api.ArtistAction;
import com.pugh.sockso.web.action.api.ArtistRelatedAction;
import com.pugh.sockso.web.action.api.ArtistTracksAction;
import com.pugh.sockso.web.action.api.ArtistsAction;
import com.pugh.sockso.web.action.api.GenresAction;
import com.pugh.sockso.web.action.api.PlaylistAction;
import com.pugh.sockso.web.action.api.PlaylistsAction;
import com.pugh.sockso.web.action.api.RootAction;
import com.pugh.sockso.web.action.api.SessionAction;
import com.pugh.sockso.web.action.api.TrackAction;
import com.pugh.sockso.web.action.api.TracksAction;
import com.google.inject.Inject;
import com.google.inject.Injector;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* End point for Sockso Web API methods.
*
*/
public class Api extends BaseAction {
private static final Logger log = Logger.getLogger( Api.class );
private final ObjectCache objectCache;
private final Injector injector;
@Inject
public Api( final ObjectCache objectCache, final Injector injector ) {
this.objectCache = objectCache;
this.injector = injector;
}
/**
* Run through API actions looking for one to handle the request
*
* @throws IOException
*
*/
@Override
public void handleRequest() throws IOException {
try {
processActions( getApiActions() );
}
catch ( final BadRequestException e ) {
TException tpl = new TException();
tpl.setMessage( e.getMessage() );
getResponse().setStatus( e.getStatusCode() );
getResponse().showJson( tpl.makeRenderer() );
}
}
/**
* This action does not require a login, but it controls logged in/out control
* for its sub actions.
*
* @return
*
*/
@Override
public boolean requiresLogin() {
return false;
}
/**
* Processes the specified API actions until one handles the request
*
* @param actions
*
*/
protected void processActions( final ApiAction[] actions ) throws BadRequestException {
final Request req = getRequest();
for ( final ApiAction action : actions ) {
if ( action.canHandle(req) && loginStatusOk(action) ) {
log.debug( "Run API action: " +action.getClass().getName() );
action.setRequest( req );
action.setResponse( getResponse() );
action.setUser( getUser() );
action.setLocale( getLocale() );
try {
action.handleRequest();
}
catch ( final Exception e ) {
log.debug( "API Exception: " +e.getMessage() );
throw new BadRequestException( e.getMessage() );
}
return;
}
}
throw new BadRequestException( "Unknown API Action" );
}
/**
* Indicates if the currently logged in status of the user is ok for
* running this action.
*
* @param action
*
* @return
*
*/
private boolean loginStatusOk( final ApiAction action ) {
if ( getProperties().get(Constants.WWW_USERS_REQUIRE_LOGIN).equals(Properties.YES) ) {
return action.requiresLogin() && getUser() == null
? false
: true;
}
return true;
}
/**
* Returns an array of all the api actions
*
* @return
*
*/
protected ApiAction[] getApiActions() {
final List<ApiAction> actions = new ArrayList<ApiAction>();
Class<ApiAction>[] actionClasses = getApiActionClasses();
for ( final Class<ApiAction> actionClass : actionClasses ) {
actions.add( injector.getInstance( actionClass ) );
}
return actions.toArray( new ApiAction[] {} );
}
/**
* Returns the class objects for all the API actions
*
* @return
*
*/
protected Class[] getApiActionClasses() {
return new Class[] {
RootAction.class,
SessionAction.class,
// playlists
PlaylistAction.class,
PlaylistsAction.class,
// tracks
TrackAction.class,
TracksAction.class,
// artists
ArtistTracksAction.class,
ArtistAction.class,
ArtistsAction.class,
ArtistRelatedAction.class,
// albums
AlbumAction.class,
AlbumsAction.class,
AlbumTracksAction.class,
// genres
GenresAction.class
};
}
}