Creating a content page resolution filter class | HCL Digital Experience
A content page resolution filter is used to customize the behavior of the content page resolution filter chain. This method is used to tailor the response to a web content request in several ways, including overriding the content item that is displayed or the portal page that is used to display a content item in the web content viewer.
About this task
The content page resolution filter chain is composed of filters that are based on the Intercepting Filter design pattern, which provides a mechanism for intercepting a request and manipulating the request and its response. When used with requests for web content, the content page resolution filter chain has default filters that process any URL parameters that are contained in the web content request and then determine which portal page has a matching web content association. The default filters occur at the end of the filter chain.
You
can customize the content page resolution filter chain by creating
custom filters that are registered with the portal through the Eclipse
plug-in framework with the extension ID com.ibm.workplace.wcm.api.ContentPageResolutionFilter
.
The sequence of filters in the filter chain is specified by a weight value associated
with each filter. To insert custom filters into the filter chain before
the default filters, you can use the weight
attribute
in the plugin.xml file. If the weight
attribute is not present, filter sequence
is determined by the getFilterChainWeight
method
of each custom filter.
- Modify parameters before calling the default filters.
- Modify the result of the default filters.
- Handle exceptions that are generated by the default filters.
- Determine whether the default filters are started.
- Modify the content path that is used as input for the default filters.
- Explicitly set a target page for displaying content.
- Determine which web content page are used, if the default filters find more than one matching web content page for the request.
- Modify the presentation template selection.
- Set HTTP response status codes.
- Send redirects to external web resources.
To use a content page resolution filter, you must create a content page resolution filter class and then register the filter by deploying it on the server.
"?urile=wcm:path:contentPath"
request before the portal state and
render parameters are set. It can then be used to change the
contentPath
and set the specific portal page to show the content
one. Refer to the following Help Center documentation for additional information: Writing links to web contentProcedure
Examples
- The
LocaleDependantSelectionFilter
example performs the default page resolution and selects a target page from the candidate pages, according to the user's locale.package com.ibm.workplace.wcm.extension.resolution; import java.util.List; import java.util.Locale; import javax.naming.InitialContext; import javax.naming.NamingException; import com.ibm.portal.ObjectID; import com.ibm.portal.model.CorLocalizedContextHome; import com.ibm.portal.model.LocalizedContext; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse; import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException; public class LocaleDependantSelectionFilter implements ContentPageResolutionFilter { CorLocalizedContextHome localizedContextHome; public LocaleDependantSelectionFilter() { try { InitialContext ctx = new InitialContext(); localizedContextHome = (CorLocalizedContextHome) ctx.lookup(CorLocalizedContextHome.JNDI_NAME); } catch(NamingException e) { e.printStackTrace(); } } public int getFilterChainWeight() { return 2; } public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) throws ContentPageResolutionException { // do standard resolution first chain.resolve(request, response); // check if more than one candidate pages List<ObjectID> candidates = response.getCandidatePageIds(); if (candidates.size() > 1) { LocalizedContext context = localizedContextHome.getLocalizedContext(request.getContext()); Locale locale = context.getPreferredSupportedLocale(); String lang = locale.getLanguage(); // find page with matching unique name for (ObjectID pageId : candidates) { if (pageId.getUniqueName().endsWith("." + lang)) { response.setPageID(pageId); break; } } } } }
- The
ChangeContentPathFilter
example overrides the path of the content that is rendered but the page resolution is performed on the originally requested content.package com.ibm.workplace.wcm.extension.resolution; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse; import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException; public class ChangeContentPathFilter implements ContentPageResolutionFilter { public int getFilterChainWeight() { return 3; } public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) throws ContentPageResolutionException { // resolve page using requested content chain.resolve(request, response); // but instead of england render UK if ("countries/world/europe/england".equals(response.getContentPath())) { response.setContentPath("countries/world/europe/uk"); } } }
- The
ResolveToSpecificPageFilter
example resolves to a specific page. No default resolution is performed in this case.package com.ibm.workplace.wcm.extension.resolution; import java.util.Arrays; import javax.naming.InitialContext; import javax.naming.NamingException; import com.ibm.portal.ObjectID; import com.ibm.portal.identification.Identification; import com.ibm.portal.serialize.SerializationException; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse; import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException; public class ResolveToSpecificPageFilter implements ContentPageResolutionFilter { private Identification identification; public ResolveToSpecificPageFilter() { try { InitialContext ctx = new InitialContext(); identification = (Identification) ctx.lookup("portal:service/Identification"); } catch (NamingException nx) { nx.printStackTrace(); } } public int getFilterChainWeight() { return 4; } public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) throws ContentPageResolutionException { try { // always resolve to page with unique name my.default.page ObjectID pageId = identification.deserialize("my.default.page"); response.setPageID(pageId); response.setCandidatePageIds(Arrays.asList(new ObjectID[]{pageId})); } catch (SerializationException e) { throw new ContentPageResolutionException(e); } } }
- The
SetResponseCodePageResolutionFilter
example checks for the requested web content item. If it does not exist, the code throws an exception that results in sending a 404 (Not found) HTTP response status code. If the content exists, resolution is delegated to other filters in the chain.package com.ibm.workplace.wcm.extension.resolution; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.Locale; import java.util.Set; import javax.servlet.http.HttpServletResponse; import com.ibm.portal.ListModel; import com.ibm.portal.LocalizedStatus; import com.ibm.portal.ModelException; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse; import com.ibm.workplace.wcm.api.extensions.resolution.ResolvedItem; import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException; public class SetResponseCodePageResolutionFilter implements ContentPageResolutionFilter { public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) throws ContentPageResolutionException { if (!itemExists(request.getItem())) { // send 404 throw new ContentPageResolutionException(new ContentNotFoundException()); } else { // forward to the chain if the web content exists chain.resolve(request, response); } } private boolean itemExists(ResolvedItem item) { return (item.getItemID() != null) && (item.getItemPath() != null); } public int getFilterChainWeight() { return 1; } private static class ContentNotFoundException extends Exception implements LocalizedStatus { private static final long serialVersionUID = 70L; private static final Set<Locale> SUPPORTED_LOCALES = new HashSet<Locale>(Arrays.asList(new Locale[] { Locale.ENGLISH })); private static final String MESSAGE = "The requested web content does not exist"; public ContentNotFoundException() { super(MESSAGE); } public int getStatus() { return HttpServletResponse.SC_NOT_FOUND; } public String getTitle(Locale locale) { return MESSAGE; } public String getDescription(Locale locale) { return MESSAGE; } public ListModel<Locale> getLocales() { return new ListModel<Locale>() { public Iterator<Locale> iterator() throws ModelException { return SUPPORTED_LOCALES.iterator(); } }; } } }
- The
SendRedirectPageResolutionFilter
example checks for the requested web content item. If the content does not exist, the code sends a redirect to http://www.ibm.com. If the content exists, the resolution is delegated to other filters in the chain.package com.ibm.workplace.wcm.extension.resolution; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; import com.ibm.portal.resolver.exceptions.ResolutionException; import com.ibm.portal.resolver.helper.CORResolutionService; import com.ibm.portal.state.exceptions.StateException; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilter; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionFilterChain; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionRequest; import com.ibm.workplace.wcm.api.extensions.resolution.ContentPageResolutionResponse; import com.ibm.workplace.wcm.api.extensions.resolution.ResolvedItem; import com.ibm.workplace.wcm.api.extensions.resolution.exceptions.ContentPageResolutionException; public class SendRedirectPageResolutionFilter implements ContentPageResolutionFilter { // the URL to redirect to private static final String URL = "http://www.ibm.com"; public void resolve(ContentPageResolutionRequest request, ContentPageResolutionResponse response, ContentPageResolutionFilterChain chain) throws ContentPageResolutionException { if (!itemExists(request.getItem())) { try { // encode to URL, this is important to prevent that the ':' // character appears in the path String encodedURL = URLEncoder.encode(URL, "UTF-8"); final URI redirectURI = new URI(com.ibm.portal.resolver.Constants.SCHEME_REDIRECT, encodedURL, null); CORResolutionService.SINGLETON.resolve(request.getResolved(), redirectURI, request.getVerb(), request.getResolutionParameters(), request.getAcceptedBindings(),request.getContext()); } catch (UnsupportedEncodingException uenc) { // should never happens as long as UTF-8 is supported throw new ContentPageResolutionException(uenc); } catch (URISyntaxException e) { throw new ContentPageResolutionException(e); } catch (StateException e) { throw new ContentPageResolutionException(e); } catch (ResolutionException e) { // do not catch the resolution exception // as this is used internally to trigger the redirect throw new ContentPageResolutionException(e); } } else { chain.resolve(request, response); } } private boolean itemExists(ResolvedItem item) { return (item.getItemID() != null) && (item.getItemPath() != null); } public int getFilterChainWeight() { return 1; } }
- The following example provides the plugin.xml file
that registers the previous sample filters.
Registering all of these filters in one system is not recommended. The filters perform overlapping operations and are also exclusive in some cases. To use one of the filters in your system, remove the other unused filters in the plugin.xml file before deploying the file.
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.0"?> <plugin id="com.ibm.workplace.wcm.extension.resolution" name="Content Page Resolution Filter" version="1.0.0" provider-name="IBM"> <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter" id="SendRedirectPageResolutionFilter"> <provider class="com.ibm.workplace.wcm.extension.resolution.SendRedirectPageResolutionFilter" weight="1"/> </extension> <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter" id="SetResponseCodePageResolutionFilter"> <provider class="com.ibm.workplace.wcm.extension.resolution.SetResponseCodePageResolutionFilter" weight="1"/> </extension> <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter" id="LocaleDependantSelectionFilter"> <provider class="com.ibm.workplace.wcm.extension.resolution.LocaleDependantSelectionFilter" weight="2"/> </extension> <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter" id="ChangeContentPathFilter"> <provider class="com.ibm.workplace.wcm.extension.resolution.ChangeContentPathFilter" weight="3"/> </extension> <extension point="com.ibm.workplace.wcm.api.ContentPageResolutionFilter" id="ResolveToSpecificPageFilter"> <provider class="com.ibm.workplace.wcm.extension.resolution.ResolveToSpecificPageFilter" weight="4"/> </extension> </plugin>