This is an automated email from the ASF dual-hosted git repository. olli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-freemarker.git
commit abb93eb2127206ee3ee07e824c9de03a4e84bfc0 Author: Oliver Lietz <[email protected]> AuthorDate: Thu Nov 3 18:03:19 2022 +0100 SLING-11660 Improve IncludeDirective streamline implementation --- .../freemarker/internal/IncludeDirective.java | 136 +++++++-------------- 1 file changed, 47 insertions(+), 89 deletions(-) diff --git a/src/main/java/org/apache/sling/scripting/freemarker/internal/IncludeDirective.java b/src/main/java/org/apache/sling/scripting/freemarker/internal/IncludeDirective.java index 1b0730f..99b9e65 100644 --- a/src/main/java/org/apache/sling/scripting/freemarker/internal/IncludeDirective.java +++ b/src/main/java/org/apache/sling/scripting/freemarker/internal/IncludeDirective.java @@ -20,6 +20,7 @@ package org.apache.sling.scripting.freemarker.internal; import java.io.IOException; import java.util.Map; +import java.util.Objects; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -36,7 +37,6 @@ import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.request.RequestDispatcherOptions; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceUtil; -import org.apache.sling.api.resource.SyntheticResource; import org.apache.sling.api.scripting.SlingBindings; import org.apache.sling.scripting.core.servlet.CaptureResponseWrapper; import org.osgi.service.component.annotations.Component; @@ -74,58 +74,52 @@ public final class IncludeDirective implements TemplateDirectiveModel { public void execute(final Environment environment, final Map parameters, final TemplateModel[] loopVars, final TemplateDirectiveBody body) throws TemplateException, IOException { final SlingHttpServletRequest slingHttpServletRequest = (SlingHttpServletRequest) DeepUnwrap.unwrap(environment.getVariable(SlingBindings.REQUEST)); - if (slingHttpServletRequest == null) { + if (Objects.isNull(slingHttpServletRequest)) { throw new TemplateException("request is null", environment); } final SlingHttpServletResponse slingHttpServletResponse = (SlingHttpServletResponse) DeepUnwrap.unwrap(environment.getVariable(SlingBindings.RESPONSE)); - if (slingHttpServletResponse == null) { + if (Objects.isNull(slingHttpServletResponse)) { throw new TemplateException("response is null", environment); } final TemplateModel templateModel = (TemplateModel) parameters.get("include"); - if (templateModel == null) { + if (Objects.isNull(templateModel)) { throw new TemplateException("include is null", environment); } final Object include = DeepUnwrap.unwrap(templateModel); - if (include == null) { + if (Objects.isNull(include)) { throw new TemplateException("unwrapping include failed", environment); } - String path = null; - if (include instanceof String) { - path = (String) include; - } - Resource resource = null; - if (include instanceof Resource) { - resource = (Resource) include; - } - - if (path == null && resource == null) { - throw new TemplateException("path and resource are null", environment); + final Resource resource = include instanceof Resource ? (Resource) include : null; + final String path = include instanceof String ? (String) include : null; + final String content; + if (!Objects.isNull(resource)) { + content = dispatch(resource, requestDispatcherOptions(parameters), slingHttpServletRequest, slingHttpServletResponse); + } else if (!Objects.isNull(path)) { + content = dispatch(path, requestDispatcherOptions(parameters), slingHttpServletRequest, slingHttpServletResponse); + } else { + throw new TemplateException("resource and path are null", environment); } - // request dispatcher options - final RequestDispatcherOptions requestDispatcherOptions = prepareRequestDispatcherOptions(parameters); - // dispatch - final String content = dispatch(resource, path, slingHttpServletRequest, slingHttpServletResponse, requestDispatcherOptions); - if (content == null) { + if (!Objects.isNull(content)) { + environment.getOut().write(content); + } else { throw new TemplateException("dispatching request failed, content is null", environment); } - environment.getOut().write(content); } - protected <T> T unwrapParameter(final String name, final Map params, final Class<T> type) throws TemplateModelException { - final Object parameter = params.get(name); - final TemplateModel templateModel = (TemplateModel) parameter; - return (T) DeepUnwrap.unwrap(templateModel); + private String unwrapParameter(final String name, final Map<?, ?> parameters) throws TemplateModelException { + final TemplateModel parameter = (TemplateModel) parameters.get(name); + return (String) DeepUnwrap.unwrap(parameter); } - protected RequestDispatcherOptions prepareRequestDispatcherOptions(final Map params) throws TemplateModelException { - final String resourceType = unwrapParameter(RESOURCE_TYPE_PARAMETER_NAME, params, String.class); - final String replaceSelectors = unwrapParameter(REPLACE_SELECTORS_PARAMETER_NAME, params, String.class); - final String addSelectors = unwrapParameter(ADD_SELECTORS_PARAMETER_NAME, params, String.class); - final String replaceSuffix = unwrapParameter(REPLACE_SUFFIX_PARAMETER_NAME, params, String.class); + private RequestDispatcherOptions requestDispatcherOptions(final Map<?, ?> parameters) throws TemplateModelException { + final String resourceType = unwrapParameter(RESOURCE_TYPE_PARAMETER_NAME, parameters); + final String replaceSelectors = unwrapParameter(REPLACE_SELECTORS_PARAMETER_NAME, parameters); + final String addSelectors = unwrapParameter(ADD_SELECTORS_PARAMETER_NAME, parameters); + final String replaceSuffix = unwrapParameter(REPLACE_SUFFIX_PARAMETER_NAME, parameters); final RequestDispatcherOptions options = new RequestDispatcherOptions(); options.setForceResourceType(resourceType); @@ -135,68 +129,32 @@ public final class IncludeDirective implements TemplateDirectiveModel { return options; } - /** - * @param resource the resource to include - * @param path the path to include - * @param slingHttpServletRequest the current request - * @param slingHttpServletResponse the current response - * @param requestDispatcherOptions the options for the request dispatcher - * @return the character response from the include call to request dispatcher - * @see "org.apache.sling.scripting.jsp.taglib.IncludeTagHandler" - */ - protected String dispatch(Resource resource, String path, final SlingHttpServletRequest slingHttpServletRequest, final SlingHttpServletResponse slingHttpServletResponse, final RequestDispatcherOptions requestDispatcherOptions) { - - // ensure the path (if set) is absolute and normalized - if (path != null) { - if (!path.startsWith("/")) { - path = slingHttpServletRequest.getResource().getPath() + "/" + path; - } - path = ResourceUtil.normalize(path); - } - - // check the resource - if (resource == null) { - if (path == null) { - // neither resource nor path is defined, use current resource - resource = slingHttpServletRequest.getResource(); - } else { - // check whether the path (would) resolve, else SyntheticRes. - final String resourceType = requestDispatcherOptions.getForceResourceType(); - final Resource tmp = slingHttpServletRequest.getResourceResolver().resolve(path); - if (tmp == null && resourceType != null) { - resource = new SyntheticResource(slingHttpServletRequest.getResourceResolver(), path, resourceType); // TODO DispatcherSyntheticResource? - // remove resource type overwrite as synthetic resource is correctly typed as requested - requestDispatcherOptions.remove(RequestDispatcherOptions.OPT_FORCE_RESOURCE_TYPE); - } - } - } - + private String dispatch(final RequestDispatcher requestDispatcher, final SlingHttpServletRequest slingHttpServletRequest, final SlingHttpServletResponse slingHttpServletResponse) { try { - // create a dispatcher for the resource or path - final RequestDispatcher dispatcher; - if (resource != null) { - dispatcher = slingHttpServletRequest.getRequestDispatcher(resource, requestDispatcherOptions); - } else { - dispatcher = slingHttpServletRequest.getRequestDispatcher(path, requestDispatcherOptions); - } - - if (dispatcher != null) { - try { - final CaptureResponseWrapper wrapper = new CaptureResponseWrapper(slingHttpServletResponse); - dispatcher.include(slingHttpServletRequest, wrapper); - if (!wrapper.isBinaryResponse()) { - return wrapper.getCapturedCharacterResponse(); - } - } catch (ServletException e) { - logger.error(e.getMessage(), e); - } - } else { - logger.error("no request dispatcher: unable to include {}/'{}'", resource, path); + final CaptureResponseWrapper wrapper = new CaptureResponseWrapper(slingHttpServletResponse); + requestDispatcher.include(slingHttpServletRequest, wrapper); + if (!wrapper.isBinaryResponse()) { + return wrapper.getCapturedCharacterResponse(); } - } catch (IOException e) { - logger.error(e.getMessage(), e); + } catch (ServletException | IOException e) { + logger.error("dispatching include failed", e); } return null; } + private String dispatch(final Resource resource, final RequestDispatcherOptions requestDispatcherOptions, final SlingHttpServletRequest slingHttpServletRequest, final SlingHttpServletResponse slingHttpServletResponse) { + final RequestDispatcher requestDispatcher = slingHttpServletRequest.getRequestDispatcher(resource, requestDispatcherOptions); + Objects.requireNonNull(requestDispatcher, String.format("getting RequestDispatcher for resource '%s' failed", resource)); + return dispatch(requestDispatcher, slingHttpServletRequest, slingHttpServletResponse); + } + + private String dispatch(final String path, final RequestDispatcherOptions requestDispatcherOptions, final SlingHttpServletRequest slingHttpServletRequest, final SlingHttpServletResponse slingHttpServletResponse) { + // ensure the path is absolute and normalized + final String absolutePath = path.startsWith("/") ? path : String.format("%s/%s", slingHttpServletRequest.getResource().getPath(), path); + final String normalizedAbsolutePath = ResourceUtil.normalize(absolutePath); + final RequestDispatcher requestDispatcher = slingHttpServletRequest.getRequestDispatcher(normalizedAbsolutePath, requestDispatcherOptions); + Objects.requireNonNull(requestDispatcher, String.format("getting RequestDispatcher for path '%s' failed", normalizedAbsolutePath)); + return dispatch(requestDispatcher, slingHttpServletRequest, slingHttpServletResponse); + } + }
