package edu.lmu.cs.headmaster.client.web.util; import java.io.IOException; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.http.NameValuePair; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.wicket.model.PropertyModel; import edu.lmu.cs.headmaster.client.web.ClientPage; /** * ServiceRelayUtils contains utility methods for communicating with the * configured service layer for this web application. */ public class ServiceRelayUtils { /** * The request methods supported by the utility methods in this class. The * enum encapsulates the code required for initializing an HttpUriRequest. */ public static enum RequestMethod { GET { public HttpUriRequest getRequest(String uri) { return new HttpGet(uri); } }, PUT { public HttpUriRequest getRequest(String uri) { return new HttpPut(uri); } }, POST { public HttpUriRequest getRequest(String uri) { return new HttpPost(uri); } }, DELETE { public HttpUriRequest getRequest(String uri) { return new HttpDelete(uri); } }; public abstract HttpUriRequest getRequest(String uri); } /** * Creates a GET request object for the service layer, for a service URI * that does not have parameters nor need username substitution. This is * pretty much just a convenience method for the version below it. */ public static HttpUriRequest createServiceLayerRequest(String serviceUri) { return createServiceLayerRequest(serviceUri, null, null, null); } /** * Creates a request object for the service layer, using the given parameters, * method, and username (which substitutes the {username} placeholder). * * This method is actually little more than a generic HTTP request creation * method since the serviceUri is expected to be fully specified. It mainly * packages operations that would normally be repeated for a single service * call into a single method, such as appending the parameter list, doing * some string substitutions, etc. */ public static HttpUriRequest createServiceLayerRequest(String serviceUri, List<NameValuePair> requestParameters, RequestMethod method, String username) { // Perform substitutions. StringBuilder uriBuilder = new StringBuilder(StringUtils.isBlank(username) ? serviceUri : serviceUri.replaceAll("\\{username\\}", username)); // Build the parameter list into the URI. uriBuilder.append(((requestParameters != null) && !requestParameters.isEmpty()) ? "?" + URLEncodedUtils.format(requestParameters, "UTF-8") : ""); // All done. return ((method != null) ? method : RequestMethod.GET).getRequest(uriBuilder.toString()); } /** * Sends the given request to the service layer, with the given ClientPage * as context. Convenience version. */ public static String sendServiceLayerRequest(HttpUriRequest request, ClientPage page) throws ClientProtocolException, IOException { // The page supplies the credentials. return sendServiceLayerRequest(request, new PropertyModel<String>(page, "session.currentUsername").getObject(), new PropertyModel<String>(page, "session.currentPassword").getObject()); } /** * Sends the given request to the service layer, and returns the response as * a string. Convenience version that does not require custom response * handling. */ public static String sendServiceLayerRequest(HttpUriRequest request, String username, String password) throws ClientProtocolException, IOException { return sendServiceLayerRequest(request, username, password, new BasicResponseHandler()); } /** * Sends the given request to the service layer, and returns the response as a string. */ public static <T> T sendServiceLayerRequest(HttpUriRequest request, String username, String password, ResponseHandler<T> responseHandler) throws ClientProtocolException, IOException { // Create and set up the HTTP client. DefaultHttpClient httpClient = new DefaultHttpClient(); httpClient.getCredentialsProvider().setCredentials( new AuthScope(null, -1), // This is strictly between the web app and the // service, so no need to get any more specific. new UsernamePasswordCredentials(username, password) ); // Issue the request, using the custom response handler if supplied. try { return httpClient.execute(request, responseHandler); } finally { httpClient.getConnectionManager().shutdown(); } } }