Looking at the source of ResourceResolver in current Sling trunk:

       for (MapEntry mapEntry : resourceMapper.getMapMaps()) {
           String[] mappedPaths = mapEntry.replace(mappedPath);
           if (mappedPaths != null) {
      ....
               break;
           }
       }

confirms that the first matching mapping entry is used as you observe. If you look at the MapEntry class used there, you'll see that it does not work according to the heirarchy of how things are defined in /etc/map but according to the complete URL pattern. The first matching entry will be used.

When you originally posted about the problem, it was when you cross from content multi 1 to multi 2 that the problem shows up. Definitely leads me to see that what you're looking for is for the resolver/mapper to understand the intention of the transformations in the map and the relationship between the content. It really isn't that smart, unfortunately. It does not understand that the content is correlated as being on the same level, or the pattern that we see when we see a numbered progression (set membership?).

When I do work on apps this is what I would call the "Application Context" where sling is only working in a request context.

I think your solution with LinkRewriter or anything else where you write the logic to correlate multi1 and multi2 are the best solutions. I also still think that whatever alias/reference methods are available at the sling level are worth looking into as is the suggestion that someone else made to use relative paths. Then you would be expressing the relationships directly (explicitly and implicitly respectively).

Hope this helps,
Jonathan 'J5' Cook


[email protected] wrote:
Hi Jonathan,

you are right about the mapping. In fact I do use /etc/map root level mappings 
like a many-to-one mapping.
E.g. similar to:

/etc/map/
|--/http
|--|--/any_host
|--|--|--/group1_multi
|--|--|--|--.sling:internalRedirect=/multi
|--|--|--/group2_multi
|--|--|--|--.sling:internalRedirect=/multi

The resolving works quite as you would expect. A request 
http://any_host/group2_multi gets correctly resolved to /multi node.

Response-rewriting also gets applied. Sling automatically uses the deepest root 
level mapping rule available. Two rules apply here to /multi, but they are on 
the same level. And in this case, Sling seems to choose just the first. So my 
request to http://any_host/group2_multi gets resolved to /multi, but the 
rewriting of links to /multi node on this page will be done to 
http://any_host/group1_multi.

The optimal solution (for my use case) would be: If there are multiple deepest 
root level mappings for a resource, choose the one which was used for resolving 
the request, not just simply the first one.

BTW: I also use CQ5, not just plain Sling ;-) But the behaviour and problem is 
quite the same.

Regards,

Matthias


Jonathan Cook <[email protected]> hat am 14. September 2009 um 18:14 
geschrieben:

It looks like you are trying to reverse a many-to-one mapping.

Let's simplify this even further

Inbound Transformation:
a/1 -> x/1
b/1 -> x/1

Desired Outbound Transformation:
x/1 -> a/1
x/1 -> b/1

This clarifies the domain of the problem, which is the behavior of the outbound transformation, which is implemented in ResourceResolver.map()

You may be confusing the problem when you refer to x/1 as being a/1 -- it's not. As soon as the inbound resolution takes place, it becomes x/1. The operations of the code attached to x/1 happen on x/1.

Taking a step back to the desired outcome rather than the specific behavior that you don't want, namely that a/1 behave as if it were x/1, I would guess that the aliasing functionality is more appropriate as a solution to your problem than the ResourceResolver/mapping system.

You need to actually have a node at a/1 (your /group1/multi1) and that node needs to be a reference to x/1 (your /multi/multi1) for the "mapping" to work as desired.

If you want to go back to looking at the ResourceResolver.map and trying to see how it could do the many-to-one mapping, you must introduce another variable so that you are in fact reversing a more complex one-to-one mapping. For instance, taking into account the original path or other members of the request object. That path (or other value) must then either be explicitly sent with the map call (essentially what you are doing with your custom LinkRewriter, I'd wager) or be derivable.

From what I understand about the algorithm used by the new ResourceResolver, it will attempt to derive the path from the originating request when a map is performed, but will not be able to when the original inbound transformation is done via a regular expression. It attempts to derive the path value that lets it turn the many-to-one mapping into a one-to-one mapping that can be reversed.

Remove use of regex from your inbound mappings and you may find that you already have functioning outbound mappings. In that case, if the output you get is not what is desired, try calling the ResourceResolver.map method explicitly. I don't work with raw SLING (only with Day CQ as of yet) so I don't know whether there IS any automatic remapping of URLs done in the vanilla SLING.

Regards,
Jonathan 'J5' Cook

P.S. I hate to advertise but I am a Day/Javascript/Java/anything-you-throw-at-me developer/architect/handyman looking for telecommute work or work in the Northern Virginia / Washington DC area. If you can help or are interested in discussing a position with me, please don't hesitate to contact me via email or GTalk.

Markus Pallo wrote:
We have a similar use case and still not solved yet ....

During searching i found

https://issues.apache.org/jira/browse/SLING-598 and thought probably it could be helpful to use some url like

http://host/group1/uuid-{uuid ofmulti_content1}

and to resolve path to parent manually if its a child of my "multi".


what do you think ?



Markus


I currently have a use case for Sling rewriting, but still found no "out-of-the-box" solution in the Sling flexible resource resolution for it.

My application has a requirement for a node which should be virtually duplicated. The example node structure is like this:

/group1
/group2
/multi
|--/multi_content1
|--/multi_content2

"Multi" should be available for each group individually. The content stays the same, but it acts differently in each group depending on the JCR-path or URI. To avoid problems with double-namings in the "real" group-content and in the "multi" group-content, I decided to use a seperate node for each multi-group with suffix "_multi".
So the structure should look virtually like this:

/group1
/group1_multi
|--/multi_content1
|--/multi_content2
/group2
/group2_multi
|--/multi_content1
|--/multi_content2
/multi
|--/multi_content1
|--/multi_content2

The goal is to handle requests like this with the same content (but different path / URI):
/group1_multi/multi_content_1  --> /multi/multi_content1
/group2_multi/multi_content_1  --> /multi/multi_content1



Reply via email to