@Override
 public Locale getLocale() {
   ActionContext ctx = ActionContext.getContext();
   if (ctx != null) {
     return ctx.getLocale();
   } else {
     return null;
   }
 }
  @Override
  protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
    if (LOG.isDebugEnabled()) {
      LOG.debug("In doExecute. finalLocation: " + finalLocation + ", renderer: " + renderer);
    }

    OutputStream os = null;
    try {
      final ActionContext actionContext = invocation.getInvocationContext();
      final HttpServletRequest request = (HttpServletRequest) actionContext.get(HTTP_REQUEST);
      final HttpServletResponse response = (HttpServletResponse) actionContext.get(HTTP_RESPONSE);
      final SimpleServletResponseWrapper responseWrapper =
          new SimpleServletResponseWrapper(response);
      final ServletContext servletContext = (ServletContext) actionContext.get(SERVLET_CONTEXT);

      ViewRenderer viewRenderer;
      if (renderer == null) {
        viewRenderer = container.getInstance(ViewRenderer.class);
      } else {
        viewRenderer = container.getInstance(ViewRenderer.class, renderer);
      }

      if (viewRenderer == null) {
        final String err =
            "Cannot get an instance of ViewRenderer with the name '" + renderer + "'.";
        LOG.error(err);
        throw new AssertionError(err);
      }

      // render view
      viewRenderer.render(
          finalLocation,
          request,
          responseWrapper,
          servletContext,
          actionContext.getLocale(),
          invocation.getStack(),
          invocation.getAction());

      // Set the content type
      response.setContentType(PDF_MIME_TYPE);

      // Set the content-disposition
      if (contentDisposition != null) {
        response.addHeader("Content-Disposition", conditionalParse(contentDisposition, invocation));
      }

      // Set the cache control headers if necessary
      if (!allowCaching) {
        response.addHeader("Pragma", "no-cache");
        response.addHeader("Cache-Control", "no-cache");
      }

      if (LOG.isTraceEnabled()) {
        LOG.trace("Content before parsing:\n" + responseWrapper.toString());
      }

      // parse response wrapper
      final Document document = parseContent(responseWrapper.toString());
      final Element head = document.head();

      // add CSS from cssPathsSet parameter
      if (cssPathsSet != null && !cssPathsSet.isEmpty()) {
        for (String css : cssPathsSet) {
          // remove leading slash
          if (css.startsWith("\\")) {
            css = css.substring(1);
          }
          head.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + css + "\" />");
        }
      }

      // add style for font family that supports unicode
      head.append(FONT_STYLE_TAG);

      final String content = document.html();

      if (LOG.isTraceEnabled()) {
        LOG.trace("Content after parsing:\n" + content);
      }

      // put pdf stream into response
      createPdfStream(content, findBaseUrl(request), response.getOutputStream());
    } finally {
      if (os != null) {
        os.close();
      }
    }
  }