package org.phms.sling.handlebars.helper.include; import com.github.jknack.handlebars.Handlebars; import com.github.jknack.handlebars.Handlebars.SafeString; import com.github.jknack.handlebars.Helper; import com.github.jknack.handlebars.Options; import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.request.RequestDispatcherOptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import java.io.IOException; public class IncludeHelper implements Helper<Object> { static final String PATH = "path"; static final String RESOURCE_TYPE = "resourceType"; static final String SELECTOR = "template"; static final String ADD_SELECTORS = "addSelectors"; static final String REPLACE_SELECTORS = "replaceSelectors"; static final String REPLACE_SUFFIX = "replaceSuffix"; private static final Logger LOG = LoggerFactory.getLogger(IncludeHelper.class); public static final String NAME = "include"; private RequestDispatcherOptions getRequestDispatcherOptions(OptionsAdapter optionsAdapter) { RequestDispatcherOptions opts = new RequestDispatcherOptions(); if (optionsAdapter.getSelector() != null) { opts.setReplaceSelectors(optionsAdapter.getSelector()); } if (optionsAdapter.getReplaceSelectors() != null) { opts.setReplaceSelectors(optionsAdapter.getReplaceSelectors()); } if (optionsAdapter.getAddSelectors() != null) { opts.setAddSelectors(optionsAdapter.getAddSelectors()); } if (StringUtils.isNotBlank(optionsAdapter.getReplaceSelectors())) { opts.setReplaceSuffix(optionsAdapter.getReplaceSelectors()); } return opts; } private SafeString include(final Options options) throws IOException, ServletException { OptionsAdapter optionsAdapter = new OptionsAdapter(options); return new Handlebars.SafeString(includeResource(optionsAdapter)); } private String includeResource(OptionsAdapter optionsAdapter) throws IOException, ServletException { RequestDispatcherOptions opts = getRequestDispatcherOptions(optionsAdapter); if (StringUtils.isNotBlank(optionsAdapter.getForceResourceType())) { opts.setForceResourceType(optionsAdapter.getForceResourceType()); } return returnInclude(optionsAdapter, opts); } private String returnInclude(OptionsAdapter optionsAdapter, RequestDispatcherOptions opts) throws IOException, ServletException { RequestDispatcher dispatcher = optionsAdapter.getRequest().getRequestDispatcher(optionsAdapter.getResource(), opts); if (dispatcher != null) { return dispatcherInclude(optionsAdapter.getRequest(), optionsAdapter.getResponse(), dispatcher); } else { LOG.error("could not include " + optionsAdapter.getResource().getPath()); return ""; } } private String dispatcherInclude(SlingHttpServletRequest request, SlingHttpServletResponse response, RequestDispatcher dispatcher) throws IOException, ServletException { try (StringResponseWrapper wrapper = new StringResponseWrapper(response)) { dispatcher.include(request, wrapper); return wrapper.getStringOutput(); } } @SuppressWarnings("unchecked") @Override public CharSequence apply(final Object context, final Options options) throws IOException { try { return include(options); } catch (final IOException e) { LOG.error("error including template", e); } catch (final ServletException e) { LOG.error("error including template", e); } return new Handlebars.SafeString(""); } }