StandardCallingConvention.java |
/* * $Id: StandardCallingConvention.java,v 1.74 2013/01/18 10:41:47 agoubard Exp $ * * See the COPYRIGHT file for redistribution and use restrictions. */ package org.xins.server; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.HashMap; import java.util.Map; import org.w3c.dom.Element; import org.xml.sax.SAXException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.xins.common.text.TextUtils; import org.xins.common.xml.ElementFormatter; /** * Standard calling convention. The technical name for this calling convention * is <em>_xins-std</em>. * * @version $Revision: 1.74 $ $Date: 2013/01/18 10:41:47 $ * @author <a href="mailto:anthony.goubard@japplis.com">Anthony Goubard</a> * @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a> */ public class StandardCallingConvention extends CallingConvention { /** * The response encoding format. */ protected static final String RESPONSE_ENCODING = "UTF-8"; /** * The content type of the HTTP response. */ protected static final String RESPONSE_CONTENT_TYPE = "text/xml; charset=" + RESPONSE_ENCODING; /** * Checks if the specified request can be handled by this calling * convention. * * <p>This method will not throw any exception. * * @param httpRequest * the HTTP request to investigate, cannot be <code>null</code>. * * @return * <code>true</code> if this calling convention is <em>possibly</em> * able to handle this request, or <code>false</code> if it * <em>definitely</em> not able to handle this request. */ protected boolean matches(HttpServletRequest httpRequest) { // If no _function parameter is specified, then there is no match return ! TextUtils.isEmpty(httpRequest.getParameter("_function")); } /** * Converts an HTTP request to a XINS request (implementation method). This * method should only be called from class CallingConvention. Only * then it is guaranteed that the <code>httpRequest</code> argument is not * <code>null</code>. * * @param httpRequest * the HTTP request, will not be <code>null</code>. * * @return * the XINS request object, never <code>null</code>. * * @throws InvalidRequestException * if the request is considerd to be invalid. * * @throws FunctionNotSpecifiedException * if the request does not indicate the name of the function to execute. */ protected FunctionRequest convertRequestImpl(HttpServletRequest httpRequest) throws InvalidRequestException, FunctionNotSpecifiedException { // Parse the parameters in the HTTP request Map<String, String> params = gatherParams(httpRequest); // Remove all invalid parameters cleanUpParameters(params); // Determine function name String functionName = httpRequest.getParameter("_function"); if (TextUtils.isEmpty(functionName)) { throw new FunctionNotSpecifiedException(); } // Get data section String dataSectionValue = httpRequest.getParameter("_data"); Element dataElement = null; if (dataSectionValue != null && dataSectionValue.length() > 0) { // Parse the data section try { dataElement = ElementFormatter.parse(dataSectionValue); // Parsing error } catch (SAXException exception) { String detail = "Cannot parse the data section."; throw new InvalidRequestException(detail, exception); } } // Define the HTTP method in the backpack Map<String, Object> backpack = new HashMap<String, Object>(); backpack.put("_httpMethod", httpRequest.getMethod()); // Construct and return the request object return new FunctionRequest(functionName, params, dataElement, backpack); } /** * Converts a XINS result to an HTTP response (implementation method). * * @param xinsResult * the XINS result object that should be converted to an HTTP response, * will not be <code>null</code>. * * @param httpResponse * the HTTP response object to configure, will not be <code>null</code>. * * @param backpack * the request backpack, will not be <code>null</code>. * * @throws IOException * if calling any of the methods in <code>httpResponse</code> causes an * I/O error. */ protected void convertResultImpl(FunctionResult xinsResult, HttpServletResponse httpResponse, Map<String, Object> backpack) throws IOException { // Set the status code and the content type Integer backpackStatusCode = (Integer) backpack.get(BackpackConstants.STATUS_CODE); if (backpackStatusCode == null) { httpResponse.setStatus(HttpServletResponse.SC_OK); } else { httpResponse.setStatus(backpackStatusCode); } httpResponse.setContentType(RESPONSE_CONTENT_TYPE); // Determine the method String method = (String) backpack.get("_httpMethod"); // Handle HEAD requests if ("HEAD".equals(method)) { StringWriter out = new StringWriter(); CallResultOutputter.output(out, xinsResult); httpResponse.setContentLength(out.getBuffer().length()); // Handle non-HEAD requests } else { Writer out = httpResponse.getWriter(); CallResultOutputter.output(out, xinsResult); out.close(); } } }