001package edu.pdx.cs410J.whitlock; 002 003import com.google.common.annotations.VisibleForTesting; 004 005import javax.servlet.ServletException; 006import javax.servlet.http.HttpServlet; 007import javax.servlet.http.HttpServletRequest; 008import javax.servlet.http.HttpServletResponse; 009import java.io.IOException; 010import java.io.PrintWriter; 011import java.util.HashMap; 012import java.util.Map; 013 014/** 015 * This servlet ultimately provides a REST API for working with an 016 * <code>AppointmentBook</code>. However, in its current state, it is an example 017 * of how to use HTTP and Java servlets to store simple key/value pairs. 018 */ 019public class AppointmentBookServlet extends HttpServlet 020{ 021 private final Map<String, AppointmentBook> appointmentBooks = new HashMap<>(); 022 023 public AppointmentBookServlet() { 024 createPreCannedAppointmentBook(); 025 } 026 027 private void createPreCannedAppointmentBook() { 028 String owner = "PreCannedOwner"; 029 AppointmentBook book = new AppointmentBook(owner); 030 this.appointmentBooks.put(owner, book); 031 032 } 033 034 /** 035 * Handles an HTTP GET request from a client by writing the value of the key 036 * specified in the "key" HTTP parameter to the HTTP response. If the "key" 037 * parameter is not specified, all of the key/value pairs are written to the 038 * HTTP response. 039 */ 040 @Override 041 protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException 042 { 043 response.setContentType( "text/plain" ); 044 045 String owner = getParameter( "owner", request ); 046 047 AppointmentBook book = getAppointmentBookForOwner(owner); 048 049 prettyPrint(book, response.getWriter()); 050 051 response.setStatus(HttpServletResponse.SC_OK); 052 } 053 054 private void prettyPrint(AppointmentBook book, PrintWriter pw) throws IOException { 055 PrettyPrinter pretty = new PrettyPrinter(pw); 056 pretty.dump(book); 057 } 058 059 @VisibleForTesting 060 AppointmentBook getAppointmentBookForOwner(String owner) { 061 return this.appointmentBooks.get(owner); 062 } 063 064 /** 065 * Handles an HTTP POST request by storing the key/value pair specified by the 066 * "key" and "value" request parameters. It writes the key/value pair to the 067 * HTTP response. 068 */ 069 @Override 070 protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException 071 { 072 response.setContentType( "text/plain" ); 073 074 String owner = getParameter("owner", request); 075 076 AppointmentBook book = getAppointmentBookForOwner(owner); 077 078 String description = getParameter("description", request); 079 String beginTime = getParameter("beginTime", request); 080 String endTime = getParameter("endTime", request); 081 082 Appointment appointment = new Appointment(description, beginTime, endTime); 083 book.addAppointment(appointment); 084 085 response.setStatus(HttpServletResponse.SC_OK); 086 } 087 088 /** 089 * Handles an HTTP DELETE request by removing all key/value pairs. This 090 * behavior is exposed for testing purposes only. It's probably not 091 * something that you'd want a real application to expose. 092 */ 093 @Override 094 protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 095 response.setContentType("text/plain"); 096 097 this.appointmentBooks.clear(); 098 099 PrintWriter pw = response.getWriter(); 100 pw.println(Messages.allMappingsDeleted()); 101 pw.flush(); 102 103 response.setStatus(HttpServletResponse.SC_OK); 104 105 } 106 107 /** 108 * Writes an error message about a missing parameter to the HTTP response. 109 * 110 * The text of the error message is created by {@link Messages#missingRequiredParameter(String)} 111 */ 112 private void missingRequiredParameter( HttpServletResponse response, String parameterName ) 113 throws IOException 114 { 115 String message = Messages.missingRequiredParameter(parameterName); 116 response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, message); 117 } 118 119 /** 120 * Returns the value of the HTTP request parameter with the given name. 121 * 122 * @return <code>null</code> if the value of the parameter is 123 * <code>null</code> or is the empty string 124 */ 125 private String getParameter(String name, HttpServletRequest request) { 126 String value = request.getParameter(name); 127 if (value == null || "".equals(value)) { 128 return null; 129 130 } else { 131 return value; 132 } 133 } 134 135 @VisibleForTesting 136 String getValueForKey(String key) { 137 throw new UnsupportedOperationException("I don't work anymore!"); 138 } 139}