Application Development, Product to Market
  • Home
  • Notes
  • Projects
  • Resources
    • Discovery Log
    • Books I Read
    • Blogs I Visit
    • Tools I Use
  • Home
  • Notes
  • Projects
  • Resources
    • Discovery Log
    • Books I Read
    • Blogs I Visit
    • Tools I Use

Programmatically find the Sling Resource from a Given a URL

1/23/2014

2 Comments

 
Picture
In CQ, ResourceResolver class can be used for resolving a Request into a Sling Resource. However, given a random URL served by a CQ instance, how do you figure out the corresponding Sling Resource of the given URL as a result of Resource Mapping definition?

Let's assume we have some Resource Mapping rules (mapping definition) set up on our Author node via /etc/map so that a sample request to, 


  URL: http://dictionary.mycompany.com/definition/visa-validity.html

will be served by the resource at,

  Sling Resource: /content/public/dictionary/legal-terms/v/visa-validity.html

You can have as many Resource Mapping rules (mapping definition) as you want. The above mapping is just an example. I want to use this example to demonstrate how did I programmatically figure out the corresponding resource from a given URL.

ResourceResolver

ResourceResolver class was implemented to return Resource. Specifically, the resolve() functions exist for this type of resolution. However, even there are three overloaded resolve() functions, none of them takes in a URL String. 
 Resource   resolve(HttpServletRequest request) 
          Deprecated. as of 2.0.4, use resolve(HttpServletRequest, String) instead.

 Resource   resolve(HttpServletRequest request, String absPath) 
          Resolves the resource from the given absPath optionally taking HttpServletRequest into account, such as the value of the Host request header.
 
Resource   resolve(String absPath) 
          Resolves the resource from the given absolute path.

the thought process

Given ResourceResolver takes in HttpServletRequest as input, if I can transform (adapt) a given URL into a HttpServletRequest using HttpServletRequestWrapper, the problem will be solved. Therefore, I implemented a ResolverRequest class which extends HttpServletRequestWrapper.

code sample

package com.company.util.http;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;

public class ResolverRequest extends HttpServletRequestWrapper {

    private final URI uri;

    public ResolverRequest(HttpServletRequest request, String uriString)
    throws URIException {
        super(request);
        uri = new URI(uriString, false);
    }

    @Override
    public String getScheme() {
        return uri.getScheme();
    }
    @Override
    public String getServerName() {
        try {
            return uri.getHost();
        } catch (URIException ue) {
            return null;
        }
    }

    @Override
    public int getServerPort() {
        return uri.getPort();
    }

    @Override
    public String getPathInfo() {
        try {
            return uri.getPath();
        } catch (URIException ue) {
            return "";
        }
    }
}
Once you have ResolverRequest class implemented and available to you, you can construct a ResolverRequest from an URL string, and pass the ResolverRequest into resolve() function of ResourceResolver to find the Resource. Problem solved:
<?xml version="1.0" encoding="UTF-8"?>
<%@page session="false"
        content
        pageEncoding="utf-8"
        import="org.apache.sling.api.request.*,
                com.company.util.http.ResolverRequest" %>
<%@include file="/libs/foundation/global.jsp" %>
<cq:defineObjects/>

<%
RequestParameter url_request_param = slingRequest.getRequestParameter("url"); // 1
pageContext.setAttribute("url_request_param", url_request_param);
%>

<result>
  <c:choose>
    <c:when test="${url_request_param == null}">
        <error>
          url parameter needed!
        </error>
    </c:when>

    <c:otherwise>
        <%
        HttpServletRequest wrappedRequest = new ResolverRequest(request, url_request_param.getString());
        Resource r = resourceResolver.resolve(wrappedRequest, wrappedRequest.getPathInfo());

        %>

        <%=r.getPath() %>

    </c:otherwise>
  </c:choose>
</result>
[1] Get the value of url parameter from the request (e.g., "http://localhost:4502/apps/company/tools/dispatcher/invalidate?url=http://dictionary.mycompany.com/definition/visa-validity.html")
2 Comments
Jeroen link
5/31/2017 05:19:55 am

Thank you sooooo much! :D

Reply
Hsufeng
5/31/2017 05:26:31 pm

You're welcome. Glad I helped.

Reply



Leave a Reply.

    Categories

    All
    Algorithm
    Concurrency
    CQ
    Data Structure
    Design Pattern
    Developer Tool
    Dynamic Programming
    Entrepreneur
    Functional Programming
    IDE
    Java
    JMX
    Marketing
    Marklogic
    Memory
    OSGI
    Performance
    Product
    Product Management
    Security
    Services
    Sling
    Social Media Programming
    Software Development

    Feed Widget

    Archives

    May 2020
    March 2020
    April 2018
    March 2018
    February 2018
    December 2017
    March 2017
    November 2016
    June 2016
    May 2016
    April 2016
    October 2015
    September 2015
    August 2015
    September 2014
    July 2014
    June 2014
    May 2014
    March 2014
    January 2014
    December 2013
    November 2013
    October 2013
    September 2013
    August 2013
    July 2013
    June 2013

    RSS Feed

in loving memory of my mother  and my 4th aunt
Photos used under Creative Commons from net_efekt, schani, visnup, Dan Zen, gadl, bobbigmac, Susana López-Urrutia, jwalsh, Philippe Put, michael pollak, oskay, Creative Tools, Violentz, Kyknoord, mobilyazilar