package com.telegraph.online.timmy.rest; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.dom4j.Document; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import com.telegraph.online.exception.ImporterException; import com.telegraph.online.exception.InputException; import com.telegraph.online.exception.ProgrammingException; import com.telegraph.online.exception.ResourceException; import com.telegraph.online.timmy.action.EscenicMessages; import com.telegraph.online.timmy.action.ImportAction; import com.telegraph.online.timmy.xml.ResponseXmlWriter; public class ImportServlet extends HttpServlet { private static final String RETURN_CONTENT_TYPE = "text/xml;charset=utf-8"; private static final String MESSAGE_OK = "OK"; private static final String ENCODING_SCHEME = "UTF-8"; private static final long serialVersionUID = 7780962167339325634L; private static Logger LOGGER = Logger.getLogger(ImportServlet.class); public void init() throws ServletException{ super.init(); } public void doDelete(HttpServletRequest request, HttpServletResponse response){ createNotSupportedResponse(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "DELETE is not supported for this resource", response); } public void doGet(HttpServletRequest request, HttpServletResponse response){ createNotSupportedResponse(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "GET is not supported for this resource", response); } public void doPost(HttpServletRequest request, HttpServletResponse response){ createNotSupportedResponse(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "POST is not supported for this resource", response); } //TODO Add XML Schema validation for returned xml //TODO Pass parameter for articletype (news, sports, etc.) to importer? (ImportAction.XML_IMPORT_SERVICE) public void doPut(HttpServletRequest request, HttpServletResponse response){ try { EscenicMessages escenicMessages; try { //Call the business process we are exposing escenicMessages = (new ImportAction()).doImport(request.getInputStream()); } catch (IOException e) { throw new ImporterException(new InputException("Unable to read the XML"), new EscenicMessages()); } //Everything went well createOkResponse(escenicMessages, response); } catch (ImporterException e){ if (e.getCause() instanceof InputException){ createErrorResponse(e, HttpServletResponse.SC_BAD_REQUEST, "Unble to parse the XML", response); } if (e.getCause() instanceof ProgrammingException){ LOGGER.error("Programmers error", e); createErrorResponse(e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unexpected error", response); } if (e.getCause() instanceof ResourceException){ LOGGER.error("Resource not available", e); createErrorResponse(e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Problem accessing resources", response); } if (e.getCause() == null){ createErrorResponse(e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Undetermined error encountered", response); } }catch (Throwable t){ LOGGER.error("Unexpected exception. All exceptions need to be wrapped in an ImporterException before being " + "thrown back to ImportServlet. Check your code and make sure you've handled and wrapped this exception appropriatly", t); createSimpleErrorResponse(t, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Undetermined error encountered", response); } } private void createOkResponse(EscenicMessages escenicMessages, HttpServletResponse response){ Document doc = createOkReturnBody(escenicMessages); try { XMLWriter xmlWriter = initResponse(response, HttpServletResponse.SC_OK); xmlWriter.write(doc); xmlWriter.flush(); } catch (Exception e) { LOGGER.error("Programmer error: Unable to return XML: " + e.getMessage(), e); } } private void createErrorResponse(ImporterException importerException, int httpReturnCode, String message, HttpServletResponse response) { Document doc = createErrorReturnBody(importerException, message); try { XMLWriter xmlWriter = initResponse(response, httpReturnCode); xmlWriter.write(doc); xmlWriter.flush(); } catch (Exception e) { LOGGER.error("Programmer error: Unable to return XML: " + e.getMessage(), e); } } private void createSimpleErrorResponse(Throwable t, int httpReturnCode, String message, HttpServletResponse response) { Document doc = ResponseXmlWriter.createCommonBody(message); try { XMLWriter xmlWriter = initResponse(response, httpReturnCode); xmlWriter.write(doc); xmlWriter.flush(); } catch (Exception e) { LOGGER.error("Programmer error: Unable to return XML: " + e.getMessage(), e); } } private void createNotSupportedResponse(int httpReturnCode, String message, HttpServletResponse response) { try { XMLWriter xmlWriter = initResponse(response, httpReturnCode); Document doc = ResponseXmlWriter.createCommonBody(message); xmlWriter.write(doc); xmlWriter.flush(); } catch (Exception e) { LOGGER.error("Programmer error: Unable to return XML: " + e.getMessage(), e); } } private static Document createOkReturnBody(EscenicMessages escenicMessages) { Document doc = ResponseXmlWriter.createCommonBody(MESSAGE_OK); ResponseXmlWriter.createInfoAndWarnings(doc.getRootElement(), escenicMessages); return doc; } private static Document createErrorReturnBody(ImporterException importerException, String errorMessage) { Document doc = ResponseXmlWriter.createCommonBody(errorMessage); ResponseXmlWriter.createInfoAndWarnings(doc.getRootElement(), importerException.getEscenicMessages()); ResponseXmlWriter.createErrors(doc.getRootElement(), importerException); return doc; } private XMLWriter initResponse(HttpServletResponse response, int httpReturnCode) throws Exception{ response.setStatus(httpReturnCode); response.setContentType(RETURN_CONTENT_TYPE); ServletOutputStream os = response.getOutputStream(); OutputFormat outformat = OutputFormat.createPrettyPrint(); outformat.setEncoding(ENCODING_SCHEME); XMLWriter writer = new XMLWriter(os, outformat); return writer; } }