示例#1
0
  protected boolean shouldExcludeProperty(String expr) {
    if (this.excludeProperties != null) {
      for (Pattern pattern : this.excludeProperties) {
        if (pattern.matcher(expr).matches()) {
          if (LOG.isDebugEnabled()) {
            LOG.debug("Ignoring property because of exclude rule: " + expr);
          }
          return true;
        }
      }
    }

    if (this.includeProperties != null) {
      for (Pattern pattern : this.includeProperties) {
        if (pattern.matcher(expr).matches()) {
          return false;
        }
      }
      if (LOG.isDebugEnabled()) {
        LOG.debug("Ignoring property because of include rule:  " + expr);
      }
      return true;
    }
    return false;
  }
示例#2
0
  /** Detect cyclic references */
  private void value(Object object, Method method) throws JSONException {
    if (object == null) {
      this.add("null");

      return;
    }

    if (this.stack.contains(object)) {
      Class clazz = object.getClass();

      // cyclic reference
      if (clazz.isPrimitive() || clazz.equals(String.class)) {
        this.process(object, method);
      } else {
        if (LOG.isDebugEnabled()) {
          LOG.debug("Cyclic reference detected on " + object);
        }

        this.add("null");
      }

      return;
    }

    this.process(object, method);
  }
示例#3
0
 /** Cleans up a request of thread locals */
 public void cleanupRequest(HttpServletRequest request) {
   Integer counterVal = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
   if (counterVal != null) {
     counterVal -= 1;
     request.setAttribute(CLEANUP_RECURSION_COUNTER, counterVal);
     if (counterVal > 0) {
       if (log.isDebugEnabled()) {
         log.debug("skipping cleanup counter=" + counterVal);
       }
       return;
     }
   }
   // always clean up the thread request, even if an action hasn't been executed
   try {
     dispatcher.cleanUpRequest(request);
   } catch (IOException e) {
     if (LOG.isWarnEnabled()) {
       LOG.warn(
           "Cannot clean up the request, some files can still remain in #0 after upload!",
           e,
           StrutsConstants.STRUTS_MULTIPART_SAVEDIR);
     }
   } finally {
     ActionContext.setContext(null);
     Dispatcher.setInstance(null);
   }
 }
  @Override
  public String doIntercept(ActionInvocation invocation) throws Exception {
    Object action = invocation.getAction();
    if (!(action instanceof NoParameters)) {
      ActionContext ac = invocation.getInvocationContext();
      final Map<String, Object> parameters = retrieveParameters(ac);

      if (LOG.isDebugEnabled()) {
        LOG.debug("Setting params " + getParameterLogMap(parameters));
      }

      if (parameters != null) {
        Map<String, Object> contextMap = ac.getContextMap();
        try {
          ReflectionContextState.setCreatingNullObjects(contextMap, true);
          ReflectionContextState.setDenyMethodExecution(contextMap, true);
          ReflectionContextState.setReportingConversionErrors(contextMap, true);

          ValueStack stack = ac.getValueStack();
          setParameters(action, stack, parameters);
        } finally {
          ReflectionContextState.setCreatingNullObjects(contextMap, false);
          ReflectionContextState.setDenyMethodExecution(contextMap, false);
          ReflectionContextState.setReportingConversionErrors(contextMap, false);
        }
      }
    }
    return invocation.invoke();
  }
  @Override
  public void setProperty(Map context, Object target, Object name, Object value)
      throws OgnlException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Entering setProperty(" + context + "," + target + "," + name + "," + value + ")");
    }

    Object key = getKey(context, name);
    Map map = (Map) target;
    map.put(key, getValue(context, value));
  }
 private void processUpload(HttpServletRequest request, String saveDir)
     throws FileUploadException, UnsupportedEncodingException {
   for (FileItem item : parseRequest(request, saveDir)) {
     if (LOG.isDebugEnabled()) {
       LOG.debug("Found item " + item.getFieldName());
     }
     if (item.isFormField()) {
       processNormalFormField(item, request.getCharacterEncoding());
     } else {
       processFileField(item);
     }
   }
 }
示例#7
0
 /**
  * Checks to see the render phase should be executed next. Mainly used for better debugging
  * messages.
  *
  * @param facesContext The current faces context
  * @param phase The phase id in execution
  * @param before Whether the phase has been executed or not
  * @return True if the response is complete
  */
 protected boolean shouldRenderResponse(FacesContext facesContext, String phase, boolean before) {
   boolean flag = false;
   if (facesContext.getRenderResponse()) {
     if (log.isDebugEnabled())
       log.debug(
           "exiting from lifecycle.execute in "
               + phase
               + " because getRenderResponse is true from one of the "
               + (before ? "before" : "after")
               + " listeners");
     flag = true;
   }
   return flag;
 }
示例#8
0
  protected void mergeTemplate(Writer writer, Template template) throws Exception {
    final TemplateEngine engine = templateEngineManager.getTemplateEngine(template, templateSuffix);
    if (engine == null) {
      throw new ConfigurationException("Unable to find a TemplateEngine for template " + template);
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug("Rendering template " + template);
    }

    final TemplateRenderingContext context =
        new TemplateRenderingContext(template, writer, getStack(), getParameters(), this);
    engine.renderTemplate(context);
  }
  @Override
  public Object getProperty(Map context, Object target, Object name) throws OgnlException {

    if (LOG.isDebugEnabled()) {
      LOG.debug("Entering getProperty (" + context + "," + target + "," + name + ")");
    }

    ReflectionContextState.updateCurrentPropertyPath(context, name);
    // if this is one of the regular index access
    // properties then just let the superclass deal with the
    // get.
    if (name instanceof String && contains(INDEX_ACCESS_PROPS, (String) name)) {
      return super.getProperty(context, target, name);
    }

    Object result = null;

    try {
      result = super.getProperty(context, target, name);
    } catch (ClassCastException ex) {
    }

    if (result == null) {
      // find the key class and convert the name to that class
      Class lastClass = (Class) context.get(XWorkConverter.LAST_BEAN_CLASS_ACCESSED);

      String lastProperty = (String) context.get(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED);
      if (lastClass == null || lastProperty == null) {
        return null;
      }
      Object key = getKey(context, name);
      Map map = (Map) target;
      result = map.get(key);

      if (result == null
          && context.get(ReflectionContextState.CREATE_NULL_OBJECTS) != null
          && objectTypeDeterminer.shouldCreateIfNew(lastClass, lastProperty, target, null, false)) {
        Class valueClass = objectTypeDeterminer.getElementClass(lastClass, lastProperty, key);

        try {
          result = objectFactory.buildBean(valueClass, context);
          map.put(key, result);
        } catch (Exception exc) {

        }
      }
    }
    return result;
  }
示例#10
0
  /**
   * Return the path to save uploaded files to (this is configurable).
   *
   * @return the path to save uploaded files to
   * @param servletContext Our ServletContext
   */
  private String getSaveDir(ServletContext servletContext) {
    String saveDir = multipartSaveDir.trim();

    if (saveDir.equals("")) {
      File tempdir = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
      if (LOG.isInfoEnabled()) {
        LOG.info(
            "Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir");
      }

      if (tempdir != null) {
        saveDir = tempdir.toString();
        setMultipartSaveDir(saveDir);
      }
    } else {
      File multipartSaveDir = new File(saveDir);

      if (!multipartSaveDir.exists()) {
        if (!multipartSaveDir.mkdirs()) {
          String logMessage;
          try {
            logMessage =
                "Could not find create multipart save directory '"
                    + multipartSaveDir.getCanonicalPath()
                    + "'.";
          } catch (IOException e) {
            logMessage =
                "Could not find create multipart save directory '"
                    + multipartSaveDir.toString()
                    + "'.";
          }
          if (devMode) {
            LOG.error(logMessage);
          } else {
            if (LOG.isWarnEnabled()) {
              LOG.warn(logMessage);
            }
          }
        }
      }
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug("saveDir=" + saveDir);
    }

    return saveDir;
  }
 /**
  * This method returns a {@link Method} in <code>action</code>. The method returned is found by
  * searching for method in <code>action</code> whose method name is equals to the result of
  * appending each <code>prefixes</code> to <code>methodName</code>. Only the first method found
  * will be returned, hence the order of <code>prefixes</code> is important. If none is found this
  * method will return null.
  *
  * @param prefixes the prefixes to prefix the <code>methodName</code>
  * @param methodName the method name to be prefixed with <code>prefixes</code>
  * @param action the action class of which the prefixed method is to be search for.
  * @return a {@link Method} if one is found, else <tt>null</tt>.
  */
 public static Method getPrefixedMethod(String[] prefixes, String methodName, Object action) {
   assert (prefixes != null);
   String capitalizedMethodName = capitalizeMethodName(methodName);
   for (String prefixe : prefixes) {
     String prefixedMethodName = prefixe + capitalizedMethodName;
     try {
       return action.getClass().getMethod(prefixedMethodName, EMPTY_CLASS_ARRAY);
     } catch (NoSuchMethodException e) {
       // hmm -- OK, try next prefix
       if (LOG.isDebugEnabled()) {
         LOG.debug("cannot find method [" + prefixedMethodName + "] in action [" + action + "]");
       }
     }
   }
   return null;
 }
  public byte[] read(String pResourceName) {
    InputStream in = null;
    try {
      ZipFile jarFile = new ZipFile(file);
      ZipEntry entry = jarFile.getEntry(pResourceName);

      // read into byte array
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      in = jarFile.getInputStream(entry);
      copy(in, out);

      return out.toByteArray();
    } catch (Exception e) {
      if (LOG.isDebugEnabled())
        LOG.debug("Unable to read file [#0] from [#1]", e, pResourceName, file.getName());
      return null;
    } finally {
      closeQuietly(in);
    }
  }
示例#13
0
 /**
  * Create HTML id element for the component and populate this component parameter map.
  * Additionally, a parameter named escapedId is populated which contains the found id value
  * filtered by {@link #escape(String)}, needed eg. for naming Javascript identifiers based on the
  * id value.
  *
  * <p>The order is as follows :-
  *
  * <ol>
  *   <li>This component id attribute
  *   <li>[containing_form_id]_[this_component_name]
  *   <li>[this_component_name]
  * </ol>
  *
  * @param form enclosing form tag
  */
 protected void populateComponentHtmlId(Form form) {
   String tryId;
   String generatedId;
   if (id != null) {
     // this check is needed for backwards compatibility with 2.1.x
     tryId = findStringIfAltSyntax(id);
   } else if (null == (generatedId = escape(name != null ? findString(name) : null))) {
     if (LOG.isDebugEnabled()) {
       LOG.debug(
           "Cannot determine id attribute for [#0], consider defining id, name or key attribute!",
           this);
     }
     tryId = null;
   } else if (form != null) {
     tryId = form.getParameters().get("id") + "_" + generatedId;
   } else {
     tryId = generatedId;
   }
   addParameter("id", tryId);
   addParameter("escapedId", escape(tryId));
 }
示例#14
0
  /**
   * Initialize and load our initial database from persistent storage.
   *
   * @param event The context initialization event
   */
  public void contextInitialized(ServletContextEvent event) {

    log.info("Initializing memory database plug in from '" + pathname + "'");

    // Remember our associated ServletContext
    this.context = event.getServletContext();

    // Construct a new database and make it available
    database = new MemoryUserDatabase();
    try {
      String path = calculatePath();
      if (log.isDebugEnabled()) {
        log.debug(" Loading database from '" + path + "'");
      }
      database.setPathname(path);
      database.open();
    } catch (Exception e) {
      log.error("Opening memory database", e);
      throw new IllegalStateException("Cannot load database from '" + pathname + "': " + e);
    }
    context.setAttribute(DATABASE_KEY, database);
  }
  private void processFileField(FileItem item) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Item is a file upload");
    }

    // Skip file uploads that don't have a file name - meaning that no file
    // was selected.
    if (item.getName() == null || item.getName().trim().length() < 1) {
      LOG.debug("No file has been uploaded for the field: " + item.getFieldName());
      return;
    }

    List<FileItem> values;
    if (files.get(item.getFieldName()) != null) {
      values = files.get(item.getFieldName());
    } else {
      values = new ArrayList<FileItem>();
    }

    values.add(item);
    files.put(item.getFieldName(), values);
  }
  private void processNormalFormField(FileItem item, String charset)
      throws UnsupportedEncodingException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Item is a normal form field");
    }
    List<String> values;
    if (params.get(item.getFieldName()) != null) {
      values = params.get(item.getFieldName());
    } else {
      values = new ArrayList<String>();
    }

    // note: see http://jira.opensymphony.com/browse/WW-633
    // basically, in some cases the charset may be null, so
    // we're just going to try to "other" method (no idea if this
    // will work)
    if (charset != null) {
      values.add(item.getString(charset));
    } else {
      values.add(item.getString());
    }
    params.put(item.getFieldName(), values);
  }
  @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();
      }
    }
  }
示例#18
0
  protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
    // Will throw a runtime exception if no "datasource" property.
    initializeProperties(invocation);

    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "Creating JasperReport for dataSource = " + dataSource + ", format = " + format,
          new Object[0]);
    }

    HttpServletRequest request =
        (HttpServletRequest)
            invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);
    HttpServletResponse response =
        (HttpServletResponse)
            invocation.getInvocationContext().get(ServletActionContext.HTTP_RESPONSE);

    // Handle IE special case: it sends a "contype" request first.
    if ("contype".equals(request.getHeader("User-Agent"))) {
      try {
        response.setContentType("application/pdf");
        response.setContentLength(0);

        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.close();
      } catch (IOException e) {
        LOG.error("Error writing report output", e);
        throw new ServletException(e.getMessage(), e);
      }
      return;
    }

    // Construct the data source for the report.
    ValueStack stack = invocation.getStack();
    ValueStackDataSource stackDataSource = null;

    Connection conn = (Connection) stack.findValue(connection);
    if (conn == null) stackDataSource = new ValueStackDataSource(stack, dataSource);

    // Determine the directory that the report file is in and set the reportDirectory parameter
    // For WW 2.1.7:
    //  ServletContext servletContext = ((ServletConfig)
    // invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONFIG)).getServletContext();
    ServletContext servletContext =
        (ServletContext)
            invocation.getInvocationContext().get(ServletActionContext.SERVLET_CONTEXT);
    String systemId = servletContext.getRealPath(finalLocation);
    Map parameters = new ValueStackShadowMap(stack);
    File directory = new File(systemId.substring(0, systemId.lastIndexOf(File.separator)));
    parameters.put("reportDirectory", directory);
    parameters.put(JRParameter.REPORT_LOCALE, invocation.getInvocationContext().getLocale());

    // put timezone in jasper report parameter
    if (timeZone != null) {
      timeZone = conditionalParse(timeZone, invocation);
      final TimeZone tz = TimeZone.getTimeZone(timeZone);
      if (tz != null) {
        // put the report time zone
        parameters.put(JRParameter.REPORT_TIME_ZONE, tz);
      }
    }

    // Add any report parameters from action to param map.
    Map reportParams = (Map) stack.findValue(reportParameters);
    if (reportParams != null) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Found report parameters; adding to parameters...", new Object[0]);
      }
      parameters.putAll(reportParams);
    }

    byte[] output;
    JasperPrint jasperPrint;

    // Fill the report and produce a print object
    try {
      JasperReport jasperReport = (JasperReport) JRLoader.loadObject(new File(systemId));
      if (conn == null)
        jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, stackDataSource);
      else jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, conn);
    } catch (JRException e) {
      LOG.error("Error building report for uri " + systemId, e);
      throw new ServletException(e.getMessage(), e);
    }

    // Export the print object to the desired output format
    try {
      if (contentDisposition != null || documentName != null) {
        final StringBuffer tmp = new StringBuffer();
        tmp.append((contentDisposition == null) ? "inline" : contentDisposition);

        if (documentName != null) {
          tmp.append("; filename=");
          tmp.append(documentName);
          tmp.append(".");
          tmp.append(format.toLowerCase());
        }

        response.setHeader("Content-disposition", tmp.toString());
      }

      JRExporter exporter;

      if (format.equals(FORMAT_PDF)) {
        response.setContentType("application/pdf");
        exporter = new JRPdfExporter();
      } else if (format.equals(FORMAT_CSV)) {
        response.setContentType("text/csv");
        exporter = new JRCsvExporter();
      } else if (format.equals(FORMAT_HTML)) {
        response.setContentType("text/html");

        // IMAGES_MAPS seems to be only supported as "backward compatible" from JasperReports 1.1.0

        Map imagesMap = new HashMap();
        request.getSession(true).setAttribute("IMAGES_MAP", imagesMap);

        exporter = new JRHtmlExporter();
        exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap);
        exporter.setParameter(
            JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + imageServletUrl);

        // Needed to support chart images:
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
        request.getSession().setAttribute("net.sf.jasperreports.j2ee.jasper_print", jasperPrint);
      } else if (format.equals(FORMAT_XLS)) {
        response.setContentType("application/vnd.ms-excel");
        exporter = new JRXlsExporter();
      } else if (format.equals(FORMAT_XML)) {
        response.setContentType("text/xml");
        exporter = new JRXmlExporter();
      } else if (format.equals(FORMAT_RTF)) {
        response.setContentType("application/rtf");
        exporter = new JRRtfExporter();
      } else {
        throw new ServletException("Unknown report format: " + format);
      }

      Map exportParams = (Map) stack.findValue(exportParameters);
      if (exportParams != null) {
        if (LOG.isDebugEnabled()) {
          LOG.debug("Found export parameters; adding to exporter parameters...", new Object[0]);
        }
        exporter.getParameters().putAll(exportParams);
      }

      output = exportReportToBytes(jasperPrint, exporter);
    } catch (JRException e) {
      String message = "Error producing " + format + " report for uri " + systemId;
      LOG.error(message, e);
      throw new ServletException(e.getMessage(), e);
    }

    response.setContentLength(output.length);

    // Will throw ServletException on IOException.
    writeReport(response, output);
  }
 public void setMinExpression(String minExpression) {
   if (LOG.isDebugEnabled()) {
     LOG.debug("${minExpression} was defined as [#0]", minExpression);
   }
   this.minExpression = minExpression;
 }
示例#20
0
 /** Cleanup any resources used to initialise Dispatcher */
 public void cleanUpAfterInit() {
   if (LOG.isDebugEnabled()) {
     LOG.debug("Cleaning up resources used to init Dispatcher");
   }
   ContainerHolder.clear();
 }
示例#21
0
  /**
   * Send an HTTP error response code.
   *
   * @param request the HttpServletRequest object.
   * @param response the HttpServletResponse object.
   * @param code the HttpServletResponse error code (see {@link
   *     javax.servlet.http.HttpServletResponse} for possible error codes).
   * @param e the Exception that is reported.
   * @param ctx the ServletContext object.
   */
  public void sendError(
      HttpServletRequest request,
      HttpServletResponse response,
      ServletContext ctx,
      int code,
      Exception e) {
    Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
    if (devModeOverride != null ? devModeOverride : devMode) {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Exception occurred during processing request: #0", e, e.getMessage());
      }
      try {
        FreemarkerManager mgr = getContainer().getInstance(FreemarkerManager.class);

        freemarker.template.Configuration config = mgr.getConfiguration(ctx);
        Template template = config.getTemplate("/org/apache/struts2/dispatcher/error.ftl");

        List<Throwable> chain = new ArrayList<Throwable>();
        Throwable cur = e;
        chain.add(cur);
        while ((cur = cur.getCause()) != null) {
          chain.add(cur);
        }

        HashMap<String, Object> data = new HashMap<String, Object>();
        data.put("exception", e);
        data.put("unknown", Location.UNKNOWN);
        data.put("chain", chain);
        data.put("locator", new Locator());

        Writer writer = new StringWriter();
        template.process(data, writer);

        response.setContentType("text/html");
        response.getWriter().write(writer.toString());
        response.getWriter().close();
      } catch (Exception exp) {
        try {
          if (LOG.isDebugEnabled()) {
            LOG.debug("Cannot show problem report!", exp);
          }
          response.sendError(
              code,
              "Unable to show problem report:\n" + exp + "\n\n" + LocationUtils.getLocation(exp));
        } catch (IOException ex) {
          // we're already sending an error, not much else we can do if more stuff breaks
        }
      }
    } else {
      try {
        if (LOG.isErrorEnabled()) {
          LOG.error("Exception occurred during processing request: #0", e, e.getMessage());
        }
        // WW-1977: Only put errors in the request when code is a 500 error
        if (code == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
          // send a http error response to use the servlet defined error handler
          // make the exception availible to the web.xml defined error page
          request.setAttribute("javax.servlet.error.exception", e);

          // for compatibility
          request.setAttribute("javax.servlet.jsp.jspException", e);
        }

        // send the error response
        response.sendError(code, e.getMessage());
      } catch (IOException e1) {
        // we're already sending an error, not much else we can do if more stuff breaks
      }
    }
  }
  public String intercept(ActionInvocation invocation) throws Exception {
    ActionContext ac = invocation.getInvocationContext();

    HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);

    if (!(request instanceof MultiPartRequestWrapper)) {
      if (LOG.isDebugEnabled()) {
        ActionProxy proxy = invocation.getProxy();
        LOG.debug(
            getTextMessage(
                "struts.messages.bypass.request",
                new String[] {proxy.getNamespace(), proxy.getActionName()}));
      }

      return invocation.invoke();
    }

    ValidationAware validation = null;

    Object action = invocation.getAction();

    if (action instanceof ValidationAware) {
      validation = (ValidationAware) action;
    }

    MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request;

    if (multiWrapper.hasErrors()) {
      for (String error : multiWrapper.getErrors()) {
        if (validation != null) {
          validation.addActionError(error);
        }

        if (LOG.isWarnEnabled()) {
          LOG.warn(error);
        }
      }
    }

    // bind allowed Files
    Enumeration fileParameterNames = multiWrapper.getFileParameterNames();
    while (fileParameterNames != null && fileParameterNames.hasMoreElements()) {
      // get the value of this input tag
      String inputName = (String) fileParameterNames.nextElement();

      // get the content type
      String[] contentType = multiWrapper.getContentTypes(inputName);

      if (isNonEmpty(contentType)) {
        // get the name of the file from the input tag
        String[] fileName = multiWrapper.getFileNames(inputName);

        if (isNonEmpty(fileName)) {
          // get a File object for the uploaded File
          File[] files = multiWrapper.getFiles(inputName);
          if (files != null && files.length > 0) {
            List<File> acceptedFiles = new ArrayList<File>(files.length);
            List<String> acceptedContentTypes = new ArrayList<String>(files.length);
            List<String> acceptedFileNames = new ArrayList<String>(files.length);
            String contentTypeName = inputName + "ContentType";
            String fileNameName = inputName + "FileName";

            for (int index = 0; index < files.length; index++) {
              if (acceptFile(
                  action,
                  files[index],
                  fileName[index],
                  contentType[index],
                  inputName,
                  validation)) {
                acceptedFiles.add(files[index]);
                acceptedContentTypes.add(contentType[index]);
                acceptedFileNames.add(fileName[index]);
              }
            }

            if (!acceptedFiles.isEmpty()) {
              Map<String, Object> params = ac.getParameters();

              params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()]));
              params.put(
                  contentTypeName,
                  acceptedContentTypes.toArray(new String[acceptedContentTypes.size()]));
              params.put(
                  fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()]));
            }
          }
        } else {
          if (LOG.isWarnEnabled()) {
            LOG.warn(
                getTextMessage(action, "struts.messages.invalid.file", new String[] {inputName}));
          }
        }
      } else {
        if (LOG.isWarnEnabled()) {
          LOG.warn(
              getTextMessage(
                  action, "struts.messages.invalid.content.type", new String[] {inputName}));
        }
      }
    }

    // invoke action
    return invocation.invoke();
  }
  /**
   * Creates any result types from the resources available in the web application. This scans the
   * web application resources using the servlet context.
   *
   * @param actionClass The action class the results are being built for.
   * @param results The results map to put the result configs created into.
   * @param resultPath The calculated path to the resources.
   * @param resultPrefix The prefix for the result. This is usually <code>/resultPath/actionName
   *     </code>.
   * @param actionName The action name which is used only for logging in this implementation.
   * @param packageConfig The package configuration which is passed along in order to determine
   * @param resultsByExtension The map of extensions to result type configuration instances.
   */
  protected void createFromResources(
      Class<?> actionClass,
      Map<String, ResultConfig> results,
      final String resultPath,
      final String resultPrefix,
      final String actionName,
      PackageConfig packageConfig,
      Map<String, ResultTypeConfig> resultsByExtension) {
    if (LOG.isTraceEnabled()) {
      LOG.trace(
          "Searching for results in the Servlet container at [#0]" + " with result prefix of [#1]",
          resultPath,
          resultPrefix);
    }

    // Build from web application using the ServletContext
    @SuppressWarnings("unchecked")
    Set<String> paths =
        servletContext.getResourcePaths(flatResultLayout ? resultPath : resultPrefix);
    if (paths != null) {
      for (String path : paths) {
        if (LOG.isTraceEnabled()) {
          LOG.trace("Processing resource path [#0]", path);
        }

        String fileName = StringUtils.substringAfterLast(path, "/");
        if (StringUtils.isBlank(fileName) || StringUtils.startsWith(fileName, ".")) {
          if (LOG.isTraceEnabled()) LOG.trace("Ignoring file without name [#0]", path);
          continue;
        } else if (fileName.lastIndexOf(".") > 0) {
          String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);

          if (conventionsService.getResultTypesByExtension(packageConfig).get(suffix) == null) {
            if (LOG.isDebugEnabled())
              LOG.debug(
                  "No result type defined for file suffix : [#0]. Ignoring file #1",
                  suffix,
                  fileName);
            continue;
          }
        }

        makeResults(actionClass, path, resultPrefix, results, packageConfig, resultsByExtension);
      }
    }

    // Building from the classpath
    String classPathLocation =
        resultPath.startsWith("/") ? resultPath.substring(1, resultPath.length()) : resultPath;
    if (LOG.isTraceEnabled()) {
      LOG.trace(
          "Searching for results in the class path at [#0]"
              + " with a result prefix of [#1] and action name [#2]",
          classPathLocation,
          resultPrefix,
          actionName);
    }

    ResourceFinder finder = new ResourceFinder(classPathLocation, getClassLoaderInterface());
    try {
      Map<String, URL> matches = finder.getResourcesMap("");
      if (matches != null) {
        Test<URL> resourceTest = getResourceTest(resultPath, actionName);
        for (Map.Entry<String, URL> entry : matches.entrySet()) {
          if (resourceTest.test(entry.getValue())) {
            if (LOG.isTraceEnabled()) {
              LOG.trace("Processing URL [#0]", entry.getKey());
            }

            String urlStr = entry.getValue().toString();
            int index = urlStr.lastIndexOf(resultPrefix);
            String path = urlStr.substring(index);
            makeResults(
                actionClass, path, resultPrefix, results, packageConfig, resultsByExtension);
          }
        }
      }
    } catch (IOException ex) {
      if (LOG.isErrorEnabled())
        LOG.error("Unable to scan directory [#0] for results", ex, classPathLocation);
    }
  }