package server.handler;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import database.Query;
/**
* Handles GET requests with uri: /meta*
* @author Joakim
*/
public class MetaDataHandler extends ContextHandler {
private static Logger log = LogManager.getLogger( MetaDataHandler.class.getName() );
public MetaDataHandler( String context ) {
super();
this.setContextPath(context);
this.setHandler( new innerHandler() );
}
/**
* Does the outer class' job
*/
private class innerHandler extends AbstractHandler {
// http://shiflett.org/blog/2011/may/the-accept-header
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
// http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
// https://restful-api-design.readthedocs.org/en/latest/resources.html
/**
* Handles GET requests with uri: /meta*
*/
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response ) throws IOException, ServletException {
//log.debug( baseRequest );
//if( !checkContext( baseRequest )) return;
String method = request.getMethod();
log.debug( baseRequest );
if( method.equals( "GET" )) {
String accept = request.getHeader( "Accept" );
if( accept.contains( "application/x-resource+json" )
|| accept.contains( "application/x-collection+json" )
|| accept.contains( "application/json" )) {
log.debug( "Accept header: \""+ accept +"\"" );
sendMetadata( request, response );
baseRequest.setHandled( true );
} else log.warn( "Unknown Accept header in GET request: \""+ accept +"\"" );
} else if( method.equals( "POST" )) {
// <host>/meta/:<id>/add=<keyword>
// <host>/meta/:<id>/remove=<keyword>
// <host>/meta/:<id>/old=<keyword>&new=<keyword>
// example 127.0.0.1/meta/:4/add=orange
String uri = baseRequest.getRequestURI();
String[] uriParts = uri.split( "/:" );
if( uriParts.length > 1 ) {
int id = 0;
try {
id = Integer.parseInt( uriParts[1].substring( 0, uriParts[1].length() - 1 ));
} catch ( NumberFormatException e ) { log.error( e, e ); return; }
String addkw = request.getParameter( "add" );
String remkw = request.getParameter( "remove" );
Query q = null;
if( addkw != null ) {
log.debug( "adding keywords" );
q = new Query();
q.addKeywords( id, addkw.split( "," ));
}
if( remkw != null ) {
log.debug( "removing keywords" );
if( q == null ) q = new Query();
q.removeKeywords( id, remkw );
}
q = null;
response.setStatus( HttpServletResponse.SC_OK );
baseRequest.setHandled( true );
return;
}
String oldkw = request.getParameter( "old" );
String newkw = request.getParameter( "new" );
if( oldkw == null || newkw == null ) return;
Query q = new Query();
int success = q.setKeyword( oldkw, newkw );
q = null;
if( success != 0 ) response.setStatus( HttpServletResponse.SC_OK );
else response.setStatus( HttpServletResponse.SC_NOT_FOUND );
baseRequest.setHandled( true );
//log.warn( "POST handler is not implemented "+ baseRequest.getRequestURI() );
}
}
/**
* Parses uri parameter and sends response
*/
private void sendMetadata( HttpServletRequest request, HttpServletResponse response ) throws IOException {
String img_id = request.getParameter( "img_id" );
String jsonString;
if( img_id != null ) {
int id = 0;
try {
id = Integer.parseInt( img_id );
jsonString = getMetadata( id );
response.setStatus( HttpServletResponse.SC_OK );
} catch( NumberFormatException e ) {
response.setStatus( HttpServletResponse.SC_BAD_REQUEST );
jsonString = "{\"error\":\"image id "+ img_id +" is not an integer.\"}";
log.warn( jsonString );
}
} else {
response.setStatus( HttpServletResponse.SC_BAD_REQUEST );
jsonString = "{\"error\":\"image id is null.\"}";
log.warn( jsonString );
}
response.setContentType( "application/json" );
response.getWriter().println( jsonString );
}
/**
* Retrieves from database and builds json string
*/
private String getMetadata( int id ) {
Query q = new Query();
String path = q.getPath( id ).replace( '\\', '/' );
String[] kw = q.getKeywords( id );
short[] dim = q.getDimensions( id );
q = null;
StringBuilder kwlist = new StringBuilder();
for ( int i=0; i<kw.length; i++ )
kwlist.append(( i==0 ? "" : "," ) +"\""+ kw[i] +"\"" );
String jsonString = "{ \"path\": \""+ path +"\""
+ ",\n \"width\": "+ dim[0]
+ ",\n \"height\": "+ dim[1]
+ ",\n \"keywords\": ["+ kwlist +"]\n}";
log.debug( "sending metadata\n"+ jsonString );
return jsonString;
}
}
}