package org.openstack.atlas.api.filters; import org.openstack.atlas.api.filters.helpers.AcceptTypes; import org.openstack.atlas.api.filters.helpers.MediaType; import org.openstack.atlas.api.filters.helpers.XmlValidationExceptionHandler; import org.openstack.atlas.api.filters.wrappers.BufferedRequestWrapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openstack.atlas.util.debug.Debug; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class XmlValidationFilter extends ValidationFilter { private final Log LOG = LogFactory.getLog(XmlValidationFilter.class); @Override public void init(FilterConfig config) throws ServletException { this.setConfig(config); } @Override public void doFilter(ServletRequest sreq, ServletResponse sresp, FilterChain fc) throws IOException, ServletException { XmlValidationExceptionHandler errHandler; Object somePojo; HttpServletRequest hreq = (HttpServletRequest) sreq; HttpServletResponse hresp = (HttpServletResponse) sresp; String accept = hreq.getHeader("Accept"); BufferedRequestWrapper breq = new BufferedRequestWrapper(hreq); String body = readFromInputStream(breq.getInputStream()); String method = hreq.getMethod(); MediaType contentMedia = MediaType.newInstance(hreq.getContentType()); String overideAccept; AcceptTypes ats = AcceptTypes.getPrefferedAcceptTypes(accept); String acceptType = ats.findSuitableMediaType(JSON, XML); errHandler = new XmlValidationExceptionHandler(); if (isHeaderTrue(hreq, "bypass-vxml")) { fc.doFilter(breq, sresp); return; } if (acceptType == null) { acceptType = JSON; // Default to Json } // Skip this filter if the request isn't XML if (!MediaType.matches(contentMedia, MediaType.newInstance(XML))) { fc.doFilter(breq, sresp); return; } if (method == null || containsMethod(method, "GET", "DELETE") || body.length() == 0) { fc.doFilter(breq, sresp); return; } overideAccept = overideAcceptType(hreq.getRequestURI()); if (overideAccept != null) { acceptType = overideAccept; } try { somePojo = xml2pojo(body, pCtx, pSchema, errHandler); if (!errHandler.getErrList().isEmpty()) { if (acceptType.equalsIgnoreCase(XML)) { sendXMLErrorResponse(hreq, hresp, BADREQ, errHandler.getErrList()); return; } if (acceptType.equalsIgnoreCase(JSON)) { sendJSONErrorResponse(hreq, hresp, BADREQ, errHandler.getErrList()); return; } } } catch (Exception ex) { String exceptionString = Debug.getExtendedStackTrace(ex); LOG.error(String.format("Unknown Exception: %s\n", exceptionString)); if (!errHandler.getErrList().isEmpty()) { if (acceptType.equalsIgnoreCase(XML)) { sendXMLErrorResponse(hreq, hresp, BADREQ, errHandler.getErrList()); return; } if (acceptType.equalsIgnoreCase(JSON)) { sendJSONErrorResponse(hreq, hresp, BADREQ, errHandler.getErrList()); return; } } else { if (acceptType.equalsIgnoreCase(XML)) { sendXMLErrorResponse(hreq, hresp, BADREQ, String.format("Unknown Exception ex: %s\n", getExtendedStackTrace(ex))); return; } if (acceptType.equalsIgnoreCase(JSON)) { sendJSONErrorResponse(hreq, hresp, BADREQ, String.format("Unknown Exception ex: %s\n", getExtendedStackTrace(ex))); return; } } } fc.doFilter(breq, sresp); } }