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; }
/** 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); }
/** 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); } } }
/** * 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; }
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; }
/** * 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); } }
/** * 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)); }
/** * 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(); } } }
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; }
/** Cleanup any resources used to initialise Dispatcher */ public void cleanUpAfterInit() { if (LOG.isDebugEnabled()) { LOG.debug("Cleaning up resources used to init Dispatcher"); } ContainerHolder.clear(); }
/** * 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); } }