GET the magic star

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

GET the magic star

Bertrand Delacretaz
Hi,

For symmetry with the way Sling handles POST to foo/*, it would be
useful to accept GET on foo/*.something as well.

One use case is, when working with client-side javascript forms
(ujax), to use the same HTML form for creating new nodes as for
editing existing nodes.

The (obvious) scenario is:

  URL U points to the content node
  GET the content to fill the form U
  user  edits the form
  submit -> POST to U

With existing content, U=/foo/mynode.html for example, that's trivial.

To create content, being able to use U=/foo/* allows for using the
exact same process and code, as long as a GET to /foo/* returns the
equivalent of an empty Node. The user can then get rid of ugly code
that differentiates between the "create new" and "edit existing"
cases.

We've been playing with this with David in the last few days, and I
have a patch based on this:

in JcrResourceResolver. resolve(HttpServletRequest request):

 if("GET".equals(request.getMethod()) &&
SyntheticStarResource.appliesToPath(pathInfo)) {
            return new SyntheticStarResource(this, pathInfo);
}

where SyntheticStarResource extends SyntheticResource, stores the
provided path and adapts to a fake Node class that returns empty
values for everything except the node path.

The result is that a GET to any URL using a star (*) as the filename
returns this SyntheticStarResource, as if there was an empty Node at
this location.

I'll attach my patch to SLING-344 - it's a quick hack, there might be
a better way but let's see if we agree on the principle before going
further.

-Bertrand

Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Tobias Bocanegra
i like this idea!
regards, toby

On Wed, Mar 26, 2008 at 10:16 AM, Bertrand Delacretaz
<[hidden email]> wrote:

> Hi,
>
>  For symmetry with the way Sling handles POST to foo/*, it would be
>  useful to accept GET on foo/*.something as well.
>
>  One use case is, when working with client-side javascript forms
>  (ujax), to use the same HTML form for creating new nodes as for
>  editing existing nodes.
>
>  The (obvious) scenario is:
>
>   URL U points to the content node
>   GET the content to fill the form U
>   user  edits the form
>   submit -> POST to U
>
>  With existing content, U=/foo/mynode.html for example, that's trivial.
>
>  To create content, being able to use U=/foo/* allows for using the
>  exact same process and code, as long as a GET to /foo/* returns the
>  equivalent of an empty Node. The user can then get rid of ugly code
>  that differentiates between the "create new" and "edit existing"
>  cases.
>
>  We've been playing with this with David in the last few days, and I
>  have a patch based on this:
>
>  in JcrResourceResolver. resolve(HttpServletRequest request):
>
>   if("GET".equals(request.getMethod()) &&
>  SyntheticStarResource.appliesToPath(pathInfo)) {
>             return new SyntheticStarResource(this, pathInfo);
>  }
>
>  where SyntheticStarResource extends SyntheticResource, stores the
>  provided path and adapts to a fake Node class that returns empty
>  values for everything except the node path.
>
>  The result is that a GET to any URL using a star (*) as the filename
>  returns this SyntheticStarResource, as if there was an empty Node at
>  this location.
>
>  I'll attach my patch to SLING-344 - it's a quick hack, there might be
>  a better way but let's see if we agree on the principle before going
>  further.
>
>  -Bertrand
>



--
-----------------------------------------< [hidden email] >---
Tobias Bocanegra, Day Management AG, Barfuesserplatz 6, CH - 4001 Basel
T +41 61 226 98 98, F +41 61 226 98 97
-----------------------------------------------< http://www.day.com >---

Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Felix Meschberger-2
In reply to this post by Bertrand Delacretaz
Hi Bertrand,

This basically makes sense. Yet, I have some comments:

(1) The EmptyRangeIterator.next() method in the patch should throw
    a NoSuchElementException instead of returning null
(2) special casing issues...

Regarding the special casing: Your patch adds a check for GET method and
"/*." in the path before actually trying to resolve the resource.
Assuming that a an actual resource will never have a "*" in its path, we
might do this as follows:

       public Resource resolve(HttpServletRequest request) throws
SlingException {
        String pathInfo = request.getPathInfo();

        // servlet directly address, so there is no path info, use "/"
then
        if (pathInfo == null) {
            pathInfo = "/";
        }

        Resource result = resolve(pathInfo);

        if (result == null) {
            if (SyntheticStarResource.appliesToPath(pathInfo)) {
                result = return new SyntheticStarResource(this,
pathInfo);
            } else {
                result = new NonExistingResource(this, pathInfo);
            }
        }

        return result;
    }

This only implements this special casing if the path does not resolve
normally (which is expected in case of this "*") and we have a single
location where we special case in the resolve method.

In addition, I also suggest to not limit this special casing to the GET
method. This would just create such a SyntheticStarResource for any
request  ...

Thinking about it, we might even take a further step and drop the
SyntheticStarResource completely and have the
NonExistingResource.adaptTo(Node.class) method return this fake node.
(or have an extension of the NonExistingResource class in the
jcr/resource bundle, which implements this adapter and which is returned
by the resolve method)

WDYT ?

Regards
Felix

Am Mittwoch, den 26.03.2008, 18:16 +0100 schrieb Bertrand Delacretaz:

> Hi,
>
> For symmetry with the way Sling handles POST to foo/*, it would be
> useful to accept GET on foo/*.something as well.
>
> One use case is, when working with client-side javascript forms
> (ujax), to use the same HTML form for creating new nodes as for
> editing existing nodes.
>
> The (obvious) scenario is:
>
>   URL U points to the content node
>   GET the content to fill the form U
>   user  edits the form
>   submit -> POST to U
>
> With existing content, U=/foo/mynode.html for example, that's trivial.
>
> To create content, being able to use U=/foo/* allows for using the
> exact same process and code, as long as a GET to /foo/* returns the
> equivalent of an empty Node. The user can then get rid of ugly code
> that differentiates between the "create new" and "edit existing"
> cases.
>
> We've been playing with this with David in the last few days, and I
> have a patch based on this:
>
> in JcrResourceResolver. resolve(HttpServletRequest request):
>
>  if("GET".equals(request.getMethod()) &&
> SyntheticStarResource.appliesToPath(pathInfo)) {
>             return new SyntheticStarResource(this, pathInfo);
> }
>
> where SyntheticStarResource extends SyntheticResource, stores the
> provided path and adapts to a fake Node class that returns empty
> values for everything except the node path.
>
> The result is that a GET to any URL using a star (*) as the filename
> returns this SyntheticStarResource, as if there was an empty Node at
> this location.
>
> I'll attach my patch to SLING-344 - it's a quick hack, there might be
> a better way but let's see if we agree on the principle before going
> further.
>
> -Bertrand


Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Bertrand Delacretaz
Hi Felix,

On Thu, Mar 27, 2008 at 2:39 PM, Felix Meschberger <[hidden email]> wrote:
>  (1) The EmptyRangeIterator.next() method in the patch should throw
>     a NoSuchElementException instead of returning null...

ok, I'll change that.

>  (2) special casing issues...

I agree with the suggested change in JcrResourceResolver.resolve, and
I'll use a new SyntheticStarResource.appliesTo(HttpServletRequest)
method so that the SyntheticStarResource can decide by itself it if is
limited to GET or applies to all HTTP methods. That'll make the
JcrResourceResolver cleaner.

> ... In addition, I also suggest to not limit this special casing to the GET
>  method. This would just create such a SyntheticStarResource for any
>  request  ...

We don't want a SyntheticStarResource for POST, do we? That might
interfere with the way we handle POST to *, see SLING-343 for example.

But I didn't check if removing the GET limitation would actually cause
problems - I just assumed it would.

> ... Thinking about it, we might even take a further step and drop the
>  SyntheticStarResource completely and have the
>  NonExistingResource.adaptTo(Node.class) method return this fake node.
>  (or have an extension of the NonExistingResource class in the
>  jcr/resource bundle, which implements this adapter and which is returned
>  by the resolve method)...

Conceptually I think this star resource is more a "synthetic" resource
than a "non existing" resource - viewed from the client side the
resource does exist, it is just internally that it doesn't have any
storage.

I'd be open to have SyntheticStarResource extend NonExistingResource
instead of SyntheticResource as it does now, but I'm not sure what
that would bring.

-Bertrand

Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Tobias Bocanegra
>  > ... In addition, I also suggest to not limit this special casing to the GET
>
> >  method. This would just create such a SyntheticStarResource for any
>  >  request  ...
>
>
> We don't want a SyntheticStarResource for POST, do we? That might
>  interfere with the way we handle POST to *, see SLING-343 for example.
yes, i think we do. currently this is a special case in the ujax post
servlet and i think it can
be nicer handled if we would have a StarResource instead of explicitly
checking for * in the servlet.
further more, a POST to /*.html could be a good hint for a redirect or
indicator for the type of status response (e.g. a /*.json could
produce a JSON status response).

> >  SyntheticStarResource completely and have the
>  >  NonExistingResource.adaptTo(Node.class) method return this fake node.
>  >  (or have an extension of the NonExistingResource class in the
>  >  jcr/resource bundle, which implements this adapter and which is returned
>
> >  by the resolve method)...
>
>  Conceptually I think this star resource is more a "synthetic" resource
>  than a "non existing" resource - viewed from the client side the
>  resource does exist, it is just internally that it doesn't have any
>  storage.
>
>  I'd be open to have SyntheticStarResource extend NonExistingResource
>  instead of SyntheticResource as it does now, but I'm not sure what
>  that would bring.
i agree with bertrand that it makes sense to differentiate between
non-existing and star.

regards,
--
Toby

Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Felix Meschberger-2
In reply to this post by Bertrand Delacretaz
Hi Bertrand,

Am Donnerstag, den 27.03.2008, 15:53 +0100 schrieb Bertrand Delacretaz:
> > ... In addition, I also suggest to not limit this special casing to the GET
> >  method. This would just create such a SyntheticStarResource for any
> >  request  ...
>
> We don't want a SyntheticStarResource for POST, do we? That might
> interfere with the way we handle POST to *, see SLING-343 for example.
>
> But I didn't check if removing the GET limitation would actually cause
> problems - I just assumed it would.

I don't think it interferes with SLING-343. In fact it would probably
make the PostServlet simpler as it would just have to check for a
trailing /* instead of also checking for extension and selectors.

Also, if we say a StarResource is not a non-existing resource, why
should this be different for POST ?

The question is how we identify a StarResource: Is it just the
trailing /* on the path ? We cannot use the resource type because this
may be overwritten by the resource type provider and we cannot use an
instanceof check because the class is private to the bundle (which IMHO
is perfectly ok).

I think, the trailing /* thing is probably good and sufficient. We might
even add helper methods to the JcrResourceUtil class:

   // return true if resource is a SyntheticStarResource
   public static boolean isStarResource(Resource resource);

   // return true if resource is a NonExistingResource
   public static boolean isNonExistingResource(Resource resource);

WDYT ?

>
> > ... Thinking about it, we might even take a further step and drop the
> >  SyntheticStarResource completely and have the
> >  NonExistingResource.adaptTo(Node.class) method return this fake node.
> >  (or have an extension of the NonExistingResource class in the
> >  jcr/resource bundle, which implements this adapter and which is returned
> >  by the resolve method)...
>
> Conceptually I think this star resource is more a "synthetic" resource
> than a "non existing" resource - viewed from the client side the
> resource does exist, it is just internally that it doesn't have any
> storage.
>
> I'd be open to have SyntheticStarResource extend NonExistingResource
> instead of SyntheticResource as it does now, but I'm not sure what
> that would bring.

Alright, I am convinced ;-)

Regards
Felix


Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Bertrand Delacretaz
Hi Felix,

On Fri, Mar 28, 2008 at 8:21 AM, Felix Meschberger <[hidden email]> wrote:
>  Am Donnerstag, den 27.03.2008, 15:53 +0100 schrieb Bertrand Delacretaz:

>  >... We don't want a SyntheticStarResource for POST, do we? That might
>  > interfere with the way we handle POST to *, see SLING-343 for example....

> ... I don't think it interferes with SLING-343. In fact it would probably
>  make the PostServlet simpler as it would just have to check for a
>  trailing /* instead of also checking for extension and selectors....

Ok, I didn't see the idea (that's also what Toby means IIUC) of first
getting a StarResource, and then using the fact that we have one to
trigger the Ujax(Sling)PostServlet. I agree with this idea - and maybe
call the class StarResource instead of SyntheticStarResource which is
a bit "heavy".

> ... The question is how we identify a StarResource: Is it just the
>  trailing /* on the path ?...

We can use the resource metadata for this, or test the path again as
you suggest.

> ... I think, the trailing /* thing is probably good and sufficient. We might
>  even add helper methods to the JcrResourceUtil class:
>
>    // return true if resource is a SyntheticStarResource
>    public static boolean isStarResource(Resource resource);
>
>    // return true if resource is a NonExistingResource
>    public static boolean isNonExistingResource(Resource resource);...

sounds good to me!

I you want to do these changes, I'm fine with that - I'd like to start
working on an example Sling application ASAP. But I can of course do
them if you're busy with other things.

-Bertrand

Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Felix Meschberger-2
Hi,

Am Freitag, den 28.03.2008, 08:34 +0100 schrieb Bertrand Delacretaz:

> Hi Felix,
>
> On Fri, Mar 28, 2008 at 8:21 AM, Felix Meschberger <[hidden email]> wrote:
> >  Am Donnerstag, den 27.03.2008, 15:53 +0100 schrieb Bertrand Delacretaz:
>
> >  >... We don't want a SyntheticStarResource for POST, do we? That might
> >  > interfere with the way we handle POST to *, see SLING-343 for example....
>
> > ... I don't think it interferes with SLING-343. In fact it would probably
> >  make the PostServlet simpler as it would just have to check for a
> >  trailing /* instead of also checking for extension and selectors....
>
> Ok, I didn't see the idea (that's also what Toby means IIUC) of first
> getting a StarResource, and then using the fact that we have one to
> trigger the Ujax(Sling)PostServlet. I agree with this idea - and maybe
> call the class StarResource instead of SyntheticStarResource which is
> a bit "heavy".

Yes, might be a good idea to rename it. It may still extend the
SyntheticResource because that is what it is  ...

>
> > ... The question is how we identify a StarResource: Is it just the
> >  trailing /* on the path ?...
>
> We can use the resource metadata for this, or test the path again as
> you suggest.
>
> > ... I think, the trailing /* thing is probably good and sufficient. We might
> >  even add helper methods to the JcrResourceUtil class:
> >
> >    // return true if resource is a SyntheticStarResource
> >    public static boolean isStarResource(Resource resource);
> >
> >    // return true if resource is a NonExistingResource
> >    public static boolean isNonExistingResource(Resource resource);...
>
> sounds good to me!
>
> I you want to do these changes, I'm fine with that - I'd like to start
> working on an example Sling application ASAP. But I can of course do
> them if you're busy with other things.

Ok, I rename the class and add the utility methods. Will also verfiy
that the UjaxPostServlet can handle the StarResource.

Regards
Felix


Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Felix Meschberger-2
In reply to this post by Tobias Bocanegra
Hi all,

Am Donnerstag, den 27.03.2008, 09:51 -0700 schrieb Tobias Bocanegra:

> >  Conceptually I think this star resource is more a "synthetic" resource
> >  than a "non existing" resource - viewed from the client side the
> >  resource does exist, it is just internally that it doesn't have any
> >  storage.
> >
> >  I'd be open to have SyntheticStarResource extend NonExistingResource
> >  instead of SyntheticResource as it does now, but I'm not sure what
> >  that would bring.
> i agree with bertrand that it makes sense to differentiate between
> non-existing and star.

Or is it the other way round ?

     NonExistingResource extends SyntheticResource

and

     StarResource extends SyntheticResource

Because both are synthetic and not reflected by really existing
resources.

This would then get another helper method in JcrResourceUtil:

     public static boolean isSyntheticResource(Resource resource);

WDYT ?

Regards
Felix


>
> regards,


Reply | Threaded
Open this post in threaded view
|

Re: GET the magic star

Bertrand Delacretaz
On Fri, Mar 28, 2008 at 10:19 AM, Felix Meschberger <[hidden email]> wrote:

> ... Or is it the other way round ?
>
>      NonExistingResource extends SyntheticResource
>
>  and
>
>      StarResource extends SyntheticResource...

Agree about that.
-Bertrand

Reply | Threaded
Open this post in threaded view
|

Request: Create Default Render for XML

Marts, Eric
In reply to this post by Tobias Bocanegra

WDYT?

Reply | Threaded
Open this post in threaded view
|

Re: Request: Create Default Render for XML

Tobias Bocanegra
I recently heard a very good statement from Neal Ford [0]: "XML should
be deprecated"

regards, toby

[0] http://javasymposium.techtarget.com/lasvegas/speakers.html#NFord

On 3/28/08, Marts, Eric <[hidden email]> wrote:
>
>  WDYT?
>

Reply | Threaded
Open this post in threaded view
|

Re: Request: Create Default Render for XML

Bertrand Delacretaz
On Sun, Mar 30, 2008 at 5:48 AM, Tobias Bocanegra
<[hidden email]> wrote:
> ...I recently heard a very good statement from Neal Ford [0]: "XML should
>  be deprecated"...

ROFL - nevertheless, if someone creates a patch to support an XML
default rendering (with tests) I guess we' accept it.

-Bertrand

Reply | Threaded
Open this post in threaded view
|

Re: Request: Create Default Render for XML

Tobias Bocanegra
>  > ...I recently heard a very good statement from Neal Ford [0]: "XML should
>  >  be deprecated"...
>
>  ROFL - nevertheless, if someone creates a patch to support an XML
>  default rendering (with tests) I guess we' accept it.
sure. the problem is that anything else than JCR docview or JCR system
view does not make sense.
so it would be convenient to use the export API of JCR.

however, the same 'depth' limitations should be applied to XML export
as to JSON, so a request to
/foo.xml should only export 1 level. hence, the provided exporters can
not be used.

if we gonna provide this, i suggest the following syntax:

<path>.<level>.<type>.xml

where level is the depth of the export, and type is either 'docview'
or 'sysview' with 'sysview' as default.

regards, toby

Reply | Threaded
Open this post in threaded view
|

Re: Request: Create Default Render for XML

Bertrand Delacretaz
On Mon, Mar 31, 2008 at 5:43 PM, Tobias Bocanegra
<[hidden email]> wrote:

>  > ...nevertheless, if someone creates a patch to support an XML
>  >  default rendering (with tests) I guess we' accept it.
>  sure. the problem is that anything else than JCR docview or JCR system
>  view does not make sense....

Agreed, and that's also easy to implement I guess, using the JCR
Session.export*View methods (am I being subtle enough in suggesting
that someone could send a patch for that? ;-)

>  ...i suggest the following syntax:
>
>  <path>.<level>.<type>.xml
>  where level is the depth of the export, and type is either 'docview'
>  or 'sysview' with 'sysview' as default....

Agree with that.

-Bertrand

Reply | Threaded
Open this post in threaded view
|

Re: Request: Create Default Render for XML

Tobias Bocanegra
> >  > ...nevertheless, if someone creates a patch to support an XML
>
> >  >  default rendering (with tests) I guess we' accept it.
>  >  sure. the problem is that anything else than JCR docview or JCR system
>
> >  view does not make sense....
>
>  Agreed, and that's also easy to implement I guess, using the JCR
>  Session.export*View methods (am I being subtle enough in suggesting
>  that someone could send a patch for that? ;-)
not that easy. the problem is that the 'depth' information cannot
easily be included. so you
need to provide some proxy ContentHandler that supreses elements
deeper than the specified level.

>  >  ...i suggest the following syntax:
>
> >
>  >  <path>.<level>.<type>.xml
>  >  where level is the depth of the export, and type is either 'docview'
>
> >  or 'sysview' with 'sysview' as default....
>
>  Agree with that.
--
toby