Last active
April 23, 2021 13:34
-
-
Save saulovenancio/2caaaaade50dc6b6331cdd57f31df931 to your computer and use it in GitHub Desktop.
ContentFragmentLinkRewriterFilter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mysite.commons.filters; | |
import static com.mysite.commons.utils.JsonUtils.applyFunctionByAttribute; | |
import java.io.IOException; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import javax.servlet.Filter; | |
import javax.servlet.FilterChain; | |
import javax.servlet.FilterConfig; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import org.apache.commons.lang3.StringUtils; | |
import org.apache.sling.api.SlingHttpServletRequest; | |
import org.apache.sling.api.SlingHttpServletResponse; | |
import org.apache.sling.api.resource.LoginException; | |
import org.apache.sling.api.resource.Resource; | |
import org.apache.sling.api.resource.ResourceResolver; | |
import org.apache.sling.api.resource.ResourceResolverFactory; | |
import org.apache.sling.engine.EngineConstants; | |
import org.osgi.service.component.annotations.Activate; | |
import org.osgi.service.component.annotations.Component; | |
import org.osgi.service.component.annotations.ConfigurationPolicy; | |
import org.osgi.service.component.annotations.Reference; | |
import org.osgi.service.metatype.annotations.AttributeDefinition; | |
import org.osgi.service.metatype.annotations.Designate; | |
import org.osgi.service.metatype.annotations.ObjectClassDefinition; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import com.google.gson.Gson; | |
import com.google.gson.JsonObject; | |
import com.mysite.commons.utils.Constants; | |
import com.mysite.commons.utils.HttpServletResponseCopier; | |
import com.mysite.commons.utils.fuctions.RewriterContentFragmentLink; | |
import com.mysite.commons.utils.fuctions.impl.RewriterContentFragmentLinkImpl; | |
/** | |
* This filter rewrites link for the Content Fragment list model exporter | |
*/ | |
@Component( | |
service = Filter.class, | |
immediate = true, | |
configurationPolicy = ConfigurationPolicy.REQUIRE, | |
property = { | |
EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST, | |
EngineConstants.SLING_FILTER_METHODS + "=GET", | |
EngineConstants.SLING_FILTER_SELECTORS + "=model", | |
EngineConstants.SLING_FILTER_EXTENSIONS + "=json" | |
} | |
) | |
@Designate(ocd = ContentFragmentLinkRewriterFilter.Config.class) | |
public class ContentFragmentLinkRewriterFilter implements Filter { | |
private static final Logger logger = LoggerFactory.getLogger(ContentFragmentLinkRewriterFilter.class); | |
private static final String ELEMENTS_ATTRIBUTE = "elements"; | |
private Config config; | |
private List<String> resourceTypes; | |
@Reference | |
private ResourceResolverFactory resolverFactory; | |
@ObjectClassDefinition(name = "AEM Content Fragment List Link Rewriter Filter", | |
description = "Configuration for filter to extend Content Fragment List functionality to rewrite links") | |
public @interface Config { | |
@AttributeDefinition(name = "Enabled", | |
description = "If this filter should not be active, rather try to delete this config. " + | |
"Only in cases where this cannot be easily accomplished uncheck this option to disable the filter.") | |
boolean enabled() default false; | |
@AttributeDefinition(name = "Resource Types", | |
description = "Resource Types to be evaluated by the filter.") | |
String[] resourceTypes(); | |
} | |
@Activate | |
public void activate(Config config) { | |
this.config = config; | |
this.resourceTypes = Arrays.asList(config.resourceTypes()); | |
} | |
@Override | |
public void init(FilterConfig filterConfig) throws ServletException { | |
// no-op | |
} | |
@Override | |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { | |
// add author check | |
if (!(response instanceof SlingHttpServletResponse) || !(request instanceof SlingHttpServletRequest)) { | |
throw new IllegalStateException("Filter not properly registered as Sling Servlet Filter"); | |
} | |
if (!config.enabled()) { | |
logger.debug("Filter disabled"); | |
filterChain.doFilter(request, response); | |
return; | |
} | |
SlingHttpServletRequest slingHttpServletRequest = (SlingHttpServletRequest) request; | |
Resource currentResource = slingHttpServletRequest.getResource(); | |
String currentResourceType = currentResource.getResourceType(); | |
if (resourceTypes.stream().noneMatch(resourceType -> StringUtils.startsWith(currentResourceType, resourceType))) { | |
logger.debug("Current resource path {} is not configured to be evaluated", currentResourceType); | |
filterChain.doFilter(request, response); | |
return; | |
} | |
// Wrap Response Class before servlet gets called | |
HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((SlingHttpServletResponse) response); | |
filterChain.doFilter(request, responseCopier); | |
// externalize links after the servlet finishes | |
responseCopier.flushBuffer(); | |
//read original response | |
byte[] responseBytes = responseCopier.getCopy(); | |
String responseString = new String(responseBytes, responseCopier.getCharacterEncoding()); | |
if (StringUtils.isNotEmpty(responseString)) { | |
//map the response to a json for manipulation | |
Gson gson = new Gson(); | |
JsonObject responseJsonObj = gson.fromJson(responseString, JsonObject.class); | |
Map<String, Object> param = new HashMap<>(); | |
param.put(ResourceResolverFactory.SUBSERVICE, this.getClass().getName()); | |
try (ResourceResolver serviceResourceResolver = resolverFactory.getServiceResourceResolver(param)) { | |
RewriterContentFragmentLink rewriterContentFragmentLink = new RewriterContentFragmentLinkImpl(serviceResourceResolver); | |
applyFunctionByAttribute(responseJsonObj, rewriterContentFragmentLink, ELEMENTS_ATTRIBUTE); | |
String jsonAsString = responseJsonObj.toString(); | |
responseCopier.resetBuffer(); | |
responseCopier.getOutputStream().write(jsonAsString.getBytes()); | |
responseCopier.setContentType(Constants.MEDIA_TYPE_APPLICATION_JSON); | |
responseCopier.setCharacterEncoding(Constants.CHARSET_UTF_8); | |
} | |
catch (LoginException e) { | |
logger.info("Could not get resource resolver for mapping URL: {}", e); | |
} | |
} | |
} | |
@Override | |
public void destroy() { | |
// no-op | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment