You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@sling.apache.org by Markus Joschko <ma...@gmail.com> on 2011/01/21 12:58:30 UTC

Create a node in a different path and redirect to that

Hi,
I face some difficulties in realizing the following case:

I have a node to which I want to add children. The problem is, that
(depending on the content of the to be created node) it is not added
to the node directly but a folder is created to which the node is
added. Like that

+ parent
     + folderA (dynamically created)
         - childABC
     + folderB (dynamically created)
         -childBAC

Because the folders might not be available, I post to parent/* and
registered a postprocessor to create the folder and move the just
created child to the corresponding folder.
That works fine. However the redirect url is still pointing to the
previous location (parent/childABC) instead of
parent/folderA/childABC.
And I can't find a way to modify the location of the response within
the postprocessor.

So I wonder whether I am on the right track or should choose a
different approach. Alternatively I could create my own postoperation
but that seems to be cumbersome as extending from ModifyOperation
isn't easy because of the dependencies in the constructor and
AbstractCreateOperation is package private. So I would basically need
to copy code directly.

Any thoughts on this?

Thanks,
 Markus

Re: Create a node in a different path and redirect to that

Posted by Markus Joschko <ma...@gmail.com>.
> Ok, I was thinking that you'd have a custom operation that will first
> create your intermediary path and then call the existing modify operation
> as service.

Haven't thought about that one. But indeed that'll work.
What about the servletcontext that is passed to the Modify operation.
Is this somehow referenceable from an osgi service?

Regards,
 Markus

Re: Create a node in a different path and redirect to that

Posted by Alexander Klimetschek <ak...@adobe.com>.
On 24.01.11 10:32, "Markus Joschko" <ma...@gmail.com> wrote:
>It seems to cover a lot of the issues. I still think that it makes
>sense to introduce preprocessors in addition.
>Even if the operations are exposed as services, as long as the code is
>package private (which makes sense), it is hard to extend them and
>decorating them appropriately only works when code can be called
>before and after the operations is executed.

Ok, I was thinking that you'd have a custom operation that will first
create your intermediary path and then call the existing modify operation
as service.

Regards,
Alex

-- 
Alexander Klimetschek
Developer // Adobe (Day) // Berlin - Basel





Re: Create a node in a different path and redirect to that

Posted by Markus Joschko <ma...@gmail.com>.
> On 24.01.11 10:10, "Markus Joschko" <ma...@gmail.com> wrote:
>>The default operations are hard/impossible to inherit and change.
>
> I think this is what should be improved. See
> https://issues.apache.org/jira/browse/SLING-1725 which is still open.
>

It seems to cover a lot of the issues. I still think that it makes
sense to introduce preprocessors in addition.
Even if the operations are exposed as services, as long as the code is
package private (which makes sense), it is hard to extend them and
decorating them appropriately only works when code can be called
before and after the operations is executed.

Is there any timeframe when 2.1.2 is due?

Regards,
 Markus

Re: Create a node in a different path and redirect to that

Posted by Alexander Klimetschek <ak...@adobe.com>.
On 24.01.11 10:10, "Markus Joschko" <ma...@gmail.com> wrote:
>The default operations are hard/impossible to inherit and change.

I think this is what should be improved. See
https://issues.apache.org/jira/browse/SLING-1725 which is still open.

Regards,
Alex

-- 
Alexander Klimetschek
Developer // Adobe (Day) // Berlin - Basel





Re: Create a node in a different path and redirect to that

Posted by Markus Joschko <ma...@gmail.com>.
Isn't it worth to introduce that hook into the POST servlet?
The default operations are hard/impossible to inherit and change. It
would be nice to have the ability to do some composition and add code
around the operations.
The postprocessor is already there so it's just the preprocessor that
is missing.
That allows to not misuse other extension points like the
namegenerator to check/setup preconditions for an operation to
succeed.

I have very good experience with frameworks that allow
decorators/interceptors on existing services.

As a side node: Why do the sling operations not use the same hooks the
external operations use? Wouldn't that be more consistent?
I see that there are some operations that need more parameters in
their constructor (modifyoperation), but doesn't that mean that the
interface for operations is not powerful enough at the moment?

Regards,
 Markus

On Fri, Jan 21, 2011 at 5:11 PM, Justin Edelson <ju...@gmail.com> wrote:
> On 1/21/11 11:06 AM, Markus Joschko wrote:
>>> You could create the folder node inside your NodeNameGenerator. This is
>>> a bit more code, but would allow you full control over how the folder is
>>> created (which it sounds like what you want).
>>
>> Ok, this is perfect then. Maybe I am a bit pedantic but is
>> NodeNameGenerator the right place to do such stuff?
>> It sounds like it is not meant to be used in that way.
>
> I agree that this wasn't the intent. But the post servlet does not have
> a mechanism to specify node types for intermediate nodes which are
> automatically created.
>
> Alternatively, you could write a PostProcessor which uses setPrimaryType
> to change the primary type from sling:Folder to whatever your custom
> folder type is, but this seems wrong too for some reason.
>
> Justin
>

Re: Create a node in a different path and redirect to that

Posted by Justin Edelson <ju...@gmail.com>.
On 1/21/11 11:06 AM, Markus Joschko wrote:
>> You could create the folder node inside your NodeNameGenerator. This is
>> a bit more code, but would allow you full control over how the folder is
>> created (which it sounds like what you want).
> 
> Ok, this is perfect then. Maybe I am a bit pedantic but is
> NodeNameGenerator the right place to do such stuff?
> It sounds like it is not meant to be used in that way.

I agree that this wasn't the intent. But the post servlet does not have
a mechanism to specify node types for intermediate nodes which are
automatically created.

Alternatively, you could write a PostProcessor which uses setPrimaryType
to change the primary type from sling:Folder to whatever your custom
folder type is, but this seems wrong too for some reason.

Justin

Re: Create a node in a different path and redirect to that

Posted by Markus Joschko <ma...@gmail.com>.
> You could create the folder node inside your NodeNameGenerator. This is
> a bit more code, but would allow you full control over how the folder is
> created (which it sounds like what you want).

Ok, this is perfect then. Maybe I am a bit pedantic but is
NodeNameGenerator the right place to do such stuff?
It sounds like it is not meant to be used in that way.

Re: Create a node in a different path and redirect to that

Posted by Justin Edelson <ju...@gmail.com>.
On 1/21/11 10:18 AM, Markus Joschko wrote:
>> There's actually a direct solution to this problem. Register a service
>> using the interface org.apache.sling.servlets.post.NodeNameGenerator
>> instead of a PostProcessor.
>>
>> Your NodeNameGenerator would look like this:
>>
>> @Component
>> @Service
>> public class MyNodeNameGenerator implements NodeNameGenerator {
>>   public String getNodeName(SlingHttpServletRequest request, String
>> parentPath, boolean requirePrefix, NodeNameGenerator defaultNNG) {
>>     if (parentPath.equals("/parent")) {
>>        return "folderA/" + defaultNNG.getNodeName(request, parentPath,
>> requirePrefix, defaultNNG);
>>      } else {
>>
>>         return null;
>>      }
>>   }
>> }
> 
> Sounds interesting. Is the folder autogenerated if not existant (which
> can be the case)?
Yes. Just like if you post to /some/path/which/doesntexist/*

> If yes, there is one caveat: The folder needs a special nodetype. Any
> chance to deal with that?
You could create the folder node inside your NodeNameGenerator. This is
a bit more code, but would allow you full control over how the folder is
created (which it sounds like what you want).

Justin

> 
> 
> 
>>
>> On 1/21/11 6:58 AM, Markus Joschko wrote:
>>> Hi,
>>> I face some difficulties in realizing the following case:
>>>
>>> I have a node to which I want to add children. The problem is, that
>>> (depending on the content of the to be created node) it is not added
>>> to the node directly but a folder is created to which the node is
>>> added. Like that
>>>
>>> + parent
>>>      + folderA (dynamically created)
>>>          - childABC
>>>      + folderB (dynamically created)
>>>          -childBAC
>>>
>>> Because the folders might not be available, I post to parent/* and
>>> registered a postprocessor to create the folder and move the just
>>> created child to the corresponding folder.
>>> That works fine. However the redirect url is still pointing to the
>>> previous location (parent/childABC) instead of
>>> parent/folderA/childABC.
>>> And I can't find a way to modify the location of the response within
>>> the postprocessor.
>>>
>>> So I wonder whether I am on the right track or should choose a
>>> different approach. Alternatively I could create my own postoperation
>>> but that seems to be cumbersome as extending from ModifyOperation
>>> isn't easy because of the dependencies in the constructor and
>>> AbstractCreateOperation is package private. So I would basically need
>>> to copy code directly.
>>>
>>> Any thoughts on this?
>>>
>>> Thanks,
>>>  Markus
>>
>>


Re: Create a node in a different path and redirect to that

Posted by Markus Joschko <ma...@gmail.com>.
> There's actually a direct solution to this problem. Register a service
> using the interface org.apache.sling.servlets.post.NodeNameGenerator
> instead of a PostProcessor.
>
> Your NodeNameGenerator would look like this:
>
> @Component
> @Service
> public class MyNodeNameGenerator implements NodeNameGenerator {
>   public String getNodeName(SlingHttpServletRequest request, String
> parentPath, boolean requirePrefix, NodeNameGenerator defaultNNG) {
>     if (parentPath.equals("/parent")) {
>        return "folderA/" + defaultNNG.getNodeName(request, parentPath,
> requirePrefix, defaultNNG);
>      } else {
>
>         return null;
>      }
>   }
> }

Sounds interesting. Is the folder autogenerated if not existant (which
can be the case)?
If yes, there is one caveat: The folder needs a special nodetype. Any
chance to deal with that?



>
> On 1/21/11 6:58 AM, Markus Joschko wrote:
>> Hi,
>> I face some difficulties in realizing the following case:
>>
>> I have a node to which I want to add children. The problem is, that
>> (depending on the content of the to be created node) it is not added
>> to the node directly but a folder is created to which the node is
>> added. Like that
>>
>> + parent
>>      + folderA (dynamically created)
>>          - childABC
>>      + folderB (dynamically created)
>>          -childBAC
>>
>> Because the folders might not be available, I post to parent/* and
>> registered a postprocessor to create the folder and move the just
>> created child to the corresponding folder.
>> That works fine. However the redirect url is still pointing to the
>> previous location (parent/childABC) instead of
>> parent/folderA/childABC.
>> And I can't find a way to modify the location of the response within
>> the postprocessor.
>>
>> So I wonder whether I am on the right track or should choose a
>> different approach. Alternatively I could create my own postoperation
>> but that seems to be cumbersome as extending from ModifyOperation
>> isn't easy because of the dependencies in the constructor and
>> AbstractCreateOperation is package private. So I would basically need
>> to copy code directly.
>>
>> Any thoughts on this?
>>
>> Thanks,
>>  Markus
>
>

Re: Create a node in a different path and redirect to that

Posted by Justin Edelson <ju...@gmail.com>.
There's actually a direct solution to this problem. Register a service
using the interface org.apache.sling.servlets.post.NodeNameGenerator
instead of a PostProcessor.

Your NodeNameGenerator would look like this:

@Component
@Service
public class MyNodeNameGenerator implements NodeNameGenerator {
   public String getNodeName(SlingHttpServletRequest request, String
parentPath, boolean requirePrefix, NodeNameGenerator defaultNNG) {
     if (parentPath.equals("/parent")) {
        return "folderA/" + defaultNNG.getNodeName(request, parentPath,
requirePrefix, defaultNNG);
      } else {

         return null;
      }
   }
}

On 1/21/11 6:58 AM, Markus Joschko wrote:
> Hi,
> I face some difficulties in realizing the following case:
> 
> I have a node to which I want to add children. The problem is, that
> (depending on the content of the to be created node) it is not added
> to the node directly but a folder is created to which the node is
> added. Like that
> 
> + parent
>      + folderA (dynamically created)
>          - childABC
>      + folderB (dynamically created)
>          -childBAC
> 
> Because the folders might not be available, I post to parent/* and
> registered a postprocessor to create the folder and move the just
> created child to the corresponding folder.
> That works fine. However the redirect url is still pointing to the
> previous location (parent/childABC) instead of
> parent/folderA/childABC.
> And I can't find a way to modify the location of the response within
> the postprocessor.
> 
> So I wonder whether I am on the right track or should choose a
> different approach. Alternatively I could create my own postoperation
> but that seems to be cumbersome as extending from ModifyOperation
> isn't easy because of the dependencies in the constructor and
> AbstractCreateOperation is package private. So I would basically need
> to copy code directly.
> 
> Any thoughts on this?
> 
> Thanks,
>  Markus


Re: Create a node in a different path and redirect to that

Posted by Markus Joschko <ma...@gmail.com>.
> On Fri, Jan 21, 2011 at 3:00 PM, Markus Joschko
> <ma...@gmail.com> wrote:
>> I see. That might work fine with XMLHTTPRequests, but not when I use
>> plain old direct
>> HTTP calls. And I find it highly inelegant.
>
> You may of course also use a regular servlet filter to set the Location header.

Before the postservlet is called? The folders do not yet exist so I
have to go into the repository and create them to have a valid path I
can use to continue processing. Can I do this in a filter?

Re: Create a node in a different path and redirect to that

Posted by Vidar Ramdal <vi...@idium.no>.
>> - In your SlingPostProcessor, be sure that you register the nodes you
>> are adding in the modifications list (which is a parameter to
>> SlingPostProcessor.process(). This list is returned in the
>> HtmlResponse of SlingPostServlet.
>> - The client examines the returned HTML (or JSON) to find the path of
>> the created node, and redirects

On Fri, Jan 21, 2011 at 3:00 PM, Markus Joschko
<ma...@gmail.com> wrote:
> I see. That might work fine with XMLHTTPRequests, but not when I use
> plain old direct
> HTTP calls. And I find it highly inelegant.

You may of course also use a regular servlet filter to set the Location header.

-- 
Vidar S. Ramdal <vi...@idium.no> - http://www.idium.no
Sommerrogata 13-15, N-0255 Oslo, Norway
+ 47 22 00 84 00
Quando omni flunkus moritatus!

Re: Create a node in a different path and redirect to that

Posted by Markus Joschko <ma...@gmail.com>.
> - In your SlingPostProcessor, be sure that you register the nodes you
> are adding in the modifications list (which is a parameter to
> SlingPostProcessor.process(). This list is returned in the
> HtmlResponse of SlingPostServlet.
> - The client examines the returned HTML (or JSON) to find the path of
> the created node, and redirects

I see. That might work fine with XMLHTTPRequests, but not when I use
plain old direct
HTTP calls. And I find it highly inelegant.

Re: Create a node in a different path and redirect to that

Posted by Vidar Ramdal <vi...@idium.no>.
> On Fri, Jan 21, 2011 at 1:04 PM, Vidar Ramdal <vi...@idium.no> wrote:
>> On Fri, Jan 21, 2011 at 12:58 PM, Markus Joschko
>> <ma...@gmail.com> wrote:
>>> Hi,
>>> I face some difficulties in realizing the following case:
>>>
>>> I have a node to which I want to add children. The problem is, that
>>> (depending on the content of the to be created node) it is not added
>>> to the node directly but a folder is created to which the node is
>>> added. Like that
>>>
>>> + parent
>>>     + folderA (dynamically created)
>>>         - childABC
>>>     + folderB (dynamically created)
>>>         -childBAC
>>>
>>> Because the folders might not be available, I post to parent/* and
>>> registered a postprocessor to create the folder and move the just
>>> created child to the corresponding folder.
>>> That works fine. However the redirect url is still pointing to the
>>> previous location (parent/childABC) instead of
>>> parent/folderA/childABC.
>>> And I can't find a way to modify the location of the response within
>>> the postprocessor.
>>>
>>> So I wonder whether I am on the right track or should choose a
>>> different approach. Alternatively I could create my own postoperation
>>> but that seems to be cumbersome as extending from ModifyOperation
>>> isn't easy because of the dependencies in the constructor and
>>> AbstractCreateOperation is package private. So I would basically need
>>> to copy code directly.
>>>
>>> Any thoughts on this?
>>
>> If you can modify the client's behaviour, you can add a :redirect
>> field to the POST request.
>> :redirect=parent/folderA/childABC
>>
>> See http://sling.apache.org/site/manipulating-content-the-slingpostservlet.html#ManipulatingContent-TheSlingPostServlet-%257B%257B%253Aredirect%257D%257D

On Fri, Jan 21, 2011 at 1:13 PM, Markus Joschko
<ma...@gmail.com> wrote:
> The problem is, that I don't know the folder name on the client
> already.  To stay in the example: folderA is not known to the client
> before.
> I need the posted node information to determine the folder name.

I see. How about:
- In your SlingPostProcessor, be sure that you register the nodes you
are adding in the modifications list (which is a parameter to
SlingPostProcessor.process(). This list is returned in the
HtmlResponse of SlingPostServlet.
- The client examines the returned HTML (or JSON) to find the path of
the created node, and redirects

-- 
Vidar S. Ramdal <vi...@idium.no> - http://www.idium.no
Sommerrogata 13-15, N-0255 Oslo, Norway
+ 47 22 00 84 00
Quando omni flunkus moritatus!

Re: Create a node in a different path and redirect to that

Posted by Markus Joschko <ma...@gmail.com>.
The problem is, that I don't know the folder name on the client
already.  To stay in the example: folderA is not known to the client
before.
I need the posted node information to determine the folder name.


On Fri, Jan 21, 2011 at 1:04 PM, Vidar Ramdal <vi...@idium.no> wrote:
> On Fri, Jan 21, 2011 at 12:58 PM, Markus Joschko
> <ma...@gmail.com> wrote:
>> Hi,
>> I face some difficulties in realizing the following case:
>>
>> I have a node to which I want to add children. The problem is, that
>> (depending on the content of the to be created node) it is not added
>> to the node directly but a folder is created to which the node is
>> added. Like that
>>
>> + parent
>>     + folderA (dynamically created)
>>         - childABC
>>     + folderB (dynamically created)
>>         -childBAC
>>
>> Because the folders might not be available, I post to parent/* and
>> registered a postprocessor to create the folder and move the just
>> created child to the corresponding folder.
>> That works fine. However the redirect url is still pointing to the
>> previous location (parent/childABC) instead of
>> parent/folderA/childABC.
>> And I can't find a way to modify the location of the response within
>> the postprocessor.
>>
>> So I wonder whether I am on the right track or should choose a
>> different approach. Alternatively I could create my own postoperation
>> but that seems to be cumbersome as extending from ModifyOperation
>> isn't easy because of the dependencies in the constructor and
>> AbstractCreateOperation is package private. So I would basically need
>> to copy code directly.
>>
>> Any thoughts on this?
>
> If you can modify the client's behaviour, you can add a :redirect
> field to the POST request.
> :redirect=parent/folderA/childABC
>
> See http://sling.apache.org/site/manipulating-content-the-slingpostservlet.html#ManipulatingContent-TheSlingPostServlet-%257B%257B%253Aredirect%257D%257D
>
>
>
> --
> Vidar S. Ramdal <vi...@idium.no> - http://www.idium.no
> Sommerrogata 13-15, N-0255 Oslo, Norway
> + 47 22 00 84 00
> Quando omni flunkus moritatus!
>

Re: Create a node in a different path and redirect to that

Posted by Vidar Ramdal <vi...@idium.no>.
On Fri, Jan 21, 2011 at 12:58 PM, Markus Joschko
<ma...@gmail.com> wrote:
> Hi,
> I face some difficulties in realizing the following case:
>
> I have a node to which I want to add children. The problem is, that
> (depending on the content of the to be created node) it is not added
> to the node directly but a folder is created to which the node is
> added. Like that
>
> + parent
>     + folderA (dynamically created)
>         - childABC
>     + folderB (dynamically created)
>         -childBAC
>
> Because the folders might not be available, I post to parent/* and
> registered a postprocessor to create the folder and move the just
> created child to the corresponding folder.
> That works fine. However the redirect url is still pointing to the
> previous location (parent/childABC) instead of
> parent/folderA/childABC.
> And I can't find a way to modify the location of the response within
> the postprocessor.
>
> So I wonder whether I am on the right track or should choose a
> different approach. Alternatively I could create my own postoperation
> but that seems to be cumbersome as extending from ModifyOperation
> isn't easy because of the dependencies in the constructor and
> AbstractCreateOperation is package private. So I would basically need
> to copy code directly.
>
> Any thoughts on this?

If you can modify the client's behaviour, you can add a :redirect
field to the POST request.
:redirect=parent/folderA/childABC

See http://sling.apache.org/site/manipulating-content-the-slingpostservlet.html#ManipulatingContent-TheSlingPostServlet-%257B%257B%253Aredirect%257D%257D



-- 
Vidar S. Ramdal <vi...@idium.no> - http://www.idium.no
Sommerrogata 13-15, N-0255 Oslo, Norway
+ 47 22 00 84 00
Quando omni flunkus moritatus!