You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Simone Tripodi <si...@apache.org> on 2012/08/06 09:50:25 UTC

[Discuss] Sitemap NG

Hi all guys,

I've had this mail draft for a long while and I think it's time to
shout it out to get your feedbacks.

Due to my involvement in Apache Commons and being strongly influenced
by the Google-Guice design, I think we could get benefit from a vision
that mixes the power of:

 * modularity;
 * Embedded DSL.

The current situation is that the sitemap takes tons of Kb of Spring
dependencies (please assume I'm not a big fan of Spring so my POV is
influenced :P) and the sitemap is described via XML. Since we can
still take the XML configuration, I'm sure - but I haven't had the
time to write even a kickoff spike, so I still don't have the proof on
hands - we could simplify the foundation of sitemap design, getting
benefits from the javac using directly the Java language to describe
the sitemap.

What I'd suggest is introducing Sitemap(s) to describe how  the
sitemap is organized, i.e.

+-------------------------+
interface Sitemap
{

    void configure( SitemapBinder binder );

}
+-------------------------+

where the {{SitemapBinder}} contains a set of APIs to allow describing
the path-matching;  a possible case could be:

+-------------------------+
public class MySitemap
    implements Sitemap
{

    public void configure( SitemapBinder binder )
    {
        binder.when( "linkmap.xml" )
                 .newCachingPipeline()
                 .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/trax.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer );

        ...

        binder.when( "linkmap2.xml" )
                 .newCachingPipeline()
                 .setStarter( new XMLGenerator(new URL( "feed2.xml" ) )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/trax2.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer );

        ...
    }

}
+-------------------------+

that would reflect what in XML would be expressed as:

+-------------------------+
<map:match pattern="linkmap.xml">
  <map:generate src="classpath:feed" />
  <map:transform src="{lm:transform.linkmap.document}"/>
  <map:serialize type="xml" />
</map:match>

...

<map:match pattern="linkmap2.xml">
  <map:generate src="classpath:feed2" />
  <map:transform src="{lm:transform.linkmap.document}"/>
  <map:serialize type="xml" />
</map:match>

...
+-------------------------+

of course, XML looks compact, but please take in consideration that
XML is not type checking, we can get errors at runtime only; that
means that a transformer can be erroneously set as generator, while
using Java APIs it would be notified at compile time.

An AbstractSitemap would help to reduce the `binder` variable verbose
and redundant call:


+-------------------------+
public class MySitemap
    extends AbstractSitemap
{

    @Override
    public void configure()
    {
       when( "linkmap.xml" )
                 .newCachingPipeline()
                 .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/trax.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer );

        ...

       when( "linkmap2.xml" )
                 .newCachingPipeline()
                 .setStarter( new XMLGenerator(new URL( "feed2.xml" ) )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/trax2.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer );

        ...
    }

}
+-------------------------+

we could also work by Sitemap composition:


+-------------------------+
public class MySitemap
    implements Sitemap
{

    public void configure( SitemapBinder binder )
    {
        binder.when( "linkmap.xml" )
                 .newCachingPipeline()
                 .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/trax.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer );

        ...

        binder.include( new MySitemap2() );

        ...
    }

}
+-------------------------+

then a special loader is used to create the application:

+-------------------------+
SitemapLoader.load( Sitemap...sitemaps );
+-------------------------+

WDYT?
TIA, all the best,
-Simo

http://people.apache.org/~simonetripodi/
http://www.99soft.org/

Re: [Discuss] Sitemap NG

Posted by Simone Tripodi <si...@apache.org>.
Hi Peter!

apologize for not having been more precise on explaining my idea:
while they look similar, I would consider the Sitemap a superset of
pure Pipeline fluent APIs.

Indeed, while a Sitemap woud _describe_ an "action" would be performed
if the current pattern matches against the input, the Pipeline APIs
would _invoke_ a Pipeline. i.e.

+-------------------------+
public class MySitemap
    implements Sitemap
{

    public void configure( SitemapBinder binder )
    {
        binder.when( "linkmap.xml" )
                 .newCachingPipeline()
                 .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/trax.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer );
        binder.when( "atom.xml" )
                 .newCachingPipeline()
                 .setStarter( new SQLTransformer( ... )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/atom.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer );
    }

}
+-------------------------+

would be different than direct pipeline executions

+-------------------------+
        newCachingPipeline()
                 .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/trax.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer )
                 .setup( System.out )
                 .execute();

        newCachingPipeline()
                 .setStarter( new SQLTransformer( ... )
                 .addComponent( new
XSLTTransformer(this.getClass().getResource("/atom.xslt") )
                 .setFinisher( XMLSerializer.createXMLSerializer )
                 .setup( System.out )
                 .execute();
+-------------------------+

The setup-execute phases, in the pipeline, would be executed by the
Sitemap framework.

best,
-Simo

http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/


On Mon, Aug 6, 2012 at 5:40 PM, Peter Hunsberger
<pe...@gmail.com> wrote:
> Hi Simone,
>
> I guess the part I'm missing is how would this differ from what is already
> in Cocoon 3 as an API?  I do get that part (most, all?) of you objective is
> to get rid of the Spring layer, so maybe the end result is essentially the
> same as the C3 API in the end?
>
> Peter Hunsberger
>
>
>
> On Mon, Aug 6, 2012 at 10:33 AM, Simone Tripodi <si...@apache.org>
> wrote:
>>
>> Hi Peter!
>>
>> My proposal is writing an intermediate layer to create sitemaps, it
>> doesn't aim to replace the existing infrastructure but IMHO it could
>> be used as the foundation to create sitemaps; while all textual
>> configurations work fine, having a more expressive and type checking
>> APIs could help - and users could still wrap them in their bigger
>> picture, making the tree objects construction easier.
>>
>> You could have a look at the Apache Commons Digester binder[1] APIs,
>> which are wrapped by the XML configuration[2] and annotated
>> elements[3]. One expressive layer to create the sitemap, multiple way
>> to bind them.
>>
>> I agree that building tree objects would still work, but Fluent
>> Interfaces would help on respecting the configuration status, i.e. the
>> first element of a Pipeline can only be a Starter, when using the "old
>> way" users are still able to setup a pipeline with no starter and find
>> the error only when executing it.
>>
>> I am sure there are cases I am not taking in consideration that would
>> break my PoC as well :P
>>
>> what do you think? You would be still able to load a graph from Neo4j
>> and setup the pipeline using directly native Java APIs - no parsing,
>> no transforming, a little faster :P
>>
>> Many thanks in advance, all the best!
>> -Simo
>>
>> [1] http://commons.apache.org/digester/guide/binder.html
>> [2] http://commons.apache.org/digester/guide/xmlrules.html
>> [3] http://commons.apache.org/digester/guide/annotations.html
>>
>> http://people.apache.org/~simonetripodi/
>> http://simonetripodi.livejournal.com/
>> http://twitter.com/simonetripodi
>> http://www.99soft.org/
>>
>>
>> On Mon, Aug 6, 2012 at 4:21 PM, Peter Hunsberger

Re: [Discuss] Sitemap NG

Posted by Peter Hunsberger <pe...@gmail.com>.
Hi Simone,

I guess the part I'm missing is how would this differ from what is already
in Cocoon 3 as an API?  I do get that part (most, all?) of you objective is
to get rid of the Spring layer, so maybe the end result is essentially the
same as the C3 API in the end?

Peter Hunsberger


On Mon, Aug 6, 2012 at 10:33 AM, Simone Tripodi <si...@apache.org>wrote:

> Hi Peter!
>
> My proposal is writing an intermediate layer to create sitemaps, it
> doesn't aim to replace the existing infrastructure but IMHO it could
> be used as the foundation to create sitemaps; while all textual
> configurations work fine, having a more expressive and type checking
> APIs could help - and users could still wrap them in their bigger
> picture, making the tree objects construction easier.
>
> You could have a look at the Apache Commons Digester binder[1] APIs,
> which are wrapped by the XML configuration[2] and annotated
> elements[3]. One expressive layer to create the sitemap, multiple way
> to bind them.
>
> I agree that building tree objects would still work, but Fluent
> Interfaces would help on respecting the configuration status, i.e. the
> first element of a Pipeline can only be a Starter, when using the "old
> way" users are still able to setup a pipeline with no starter and find
> the error only when executing it.
>
> I am sure there are cases I am not taking in consideration that would
> break my PoC as well :P
>
> what do you think? You would be still able to load a graph from Neo4j
> and setup the pipeline using directly native Java APIs - no parsing,
> no transforming, a little faster :P
>
> Many thanks in advance, all the best!
> -Simo
>
> [1] http://commons.apache.org/digester/guide/binder.html
> [2] http://commons.apache.org/digester/guide/xmlrules.html
> [3] http://commons.apache.org/digester/guide/annotations.html
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
>
> On Mon, Aug 6, 2012 at 4:21 PM, Peter Hunsberger
>

Re: [Discuss] Sitemap NG

Posted by Simone Tripodi <si...@apache.org>.
Hi Peter!

My proposal is writing an intermediate layer to create sitemaps, it
doesn't aim to replace the existing infrastructure but IMHO it could
be used as the foundation to create sitemaps; while all textual
configurations work fine, having a more expressive and type checking
APIs could help - and users could still wrap them in their bigger
picture, making the tree objects construction easier.

You could have a look at the Apache Commons Digester binder[1] APIs,
which are wrapped by the XML configuration[2] and annotated
elements[3]. One expressive layer to create the sitemap, multiple way
to bind them.

I agree that building tree objects would still work, but Fluent
Interfaces would help on respecting the configuration status, i.e. the
first element of a Pipeline can only be a Starter, when using the "old
way" users are still able to setup a pipeline with no starter and find
the error only when executing it.

I am sure there are cases I am not taking in consideration that would
break my PoC as well :P

what do you think? You would be still able to load a graph from Neo4j
and setup the pipeline using directly native Java APIs - no parsing,
no transforming, a little faster :P

Many thanks in advance, all the best!
-Simo

[1] http://commons.apache.org/digester/guide/binder.html
[2] http://commons.apache.org/digester/guide/xmlrules.html
[3] http://commons.apache.org/digester/guide/annotations.html

http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/


On Mon, Aug 6, 2012 at 4:21 PM, Peter Hunsberger
<pe...@gmail.com> wrote:
> Hi Simone,
>
> long time ago we had discussions on alternate languages for the C2 Sitemap,
> I used to want to do them in XSLT (as opposed to XML) with Java extensions
> to implement the actual interface from the XSLT to the resulting Cocoon
> object tree for the sitemap. These days I sometimes wonder if I could build
> sitemaps in Neo4J and have Cocoon read them in via it's Neo4Js REST
> interface (or more directly)...
>
> In some ways it seems Cocoon 3 is already aimed at  most of what you outline
> or is this in addition to the way you can do Java pipelines there?
>
> Peter Hunsberger
>
>
>
> On Mon, Aug 6, 2012 at 2:50 AM, Simone Tripodi <si...@apache.org>
> wrote:
>>
>> Hi all guys,
>>
>> I've had this mail draft for a long while and I think it's time to
>> shout it out to get your feedbacks.
>>
>> Due to my involvement in Apache Commons and being strongly influenced
>> by the Google-Guice design, I think we could get benefit from a vision
>> that mixes the power of:
>>
>>  * modularity;
>>  * Embedded DSL.
>>
>> The current situation is that the sitemap takes tons of Kb of Spring
>> dependencies (please assume I'm not a big fan of Spring so my POV is
>> influenced :P) and the sitemap is described via XML. Since we can
>> still take the XML configuration, I'm sure - but I haven't had the
>> time to write even a kickoff spike, so I still don't have the proof on
>> hands - we could simplify the foundation of sitemap design, getting
>> benefits from the javac using directly the Java language to describe
>> the sitemap.
>>
>> What I'd suggest is introducing Sitemap(s) to describe how  the
>> sitemap is organized, i.e.
>>
>> +-------------------------+
>> interface Sitemap
>> {
>>
>>     void configure( SitemapBinder binder );
>>
>> }
>> +-------------------------+
>>
>> where the {{SitemapBinder}} contains a set of APIs to allow describing
>> the path-matching;  a possible case could be:
>>
>> +-------------------------+
>> public class MySitemap
>>     implements Sitemap
>> {
>>
>>     public void configure( SitemapBinder binder )
>>     {
>>         binder.when( "linkmap.xml" )
>>                  .newCachingPipeline()
>>                  .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
>>                  .addComponent( new
>> XSLTTransformer(this.getClass().getResource("/trax.xslt") )
>>                  .setFinisher( XMLSerializer.createXMLSerializer );
>>
>>         ...
>>
>>         binder.when( "linkmap2.xml" )
>>                  .newCachingPipeline()
>>                  .setStarter( new XMLGenerator(new URL( "feed2.xml" ) )
>>                  .addComponent( new
>> XSLTTransformer(this.getClass().getResource("/trax2.xslt") )
>>                  .setFinisher( XMLSerializer.createXMLSerializer );
>>
>>         ...
>>     }
>>
>> }
>> +-------------------------+
>>
>> that would reflect what in XML would be expressed as:
>>
>> +-------------------------+
>> <map:match pattern="linkmap.xml">
>>   <map:generate src="classpath:feed" />
>>   <map:transform src="{lm:transform.linkmap.document}"/>
>>   <map:serialize type="xml" />
>> </map:match>
>>
>> ...
>>
>> <map:match pattern="linkmap2.xml">
>>   <map:generate src="classpath:feed2" />
>>   <map:transform src="{lm:transform.linkmap.document}"/>
>>   <map:serialize type="xml" />
>> </map:match>
>>
>> ...
>> +-------------------------+
>>
>> of course, XML looks compact, but please take in consideration that
>> XML is not type checking, we can get errors at runtime only; that
>> means that a transformer can be erroneously set as generator, while
>> using Java APIs it would be notified at compile time.
>>
>> An AbstractSitemap would help to reduce the `binder` variable verbose
>> and redundant call:
>>
>>
>> +-------------------------+
>> public class MySitemap
>>     extends AbstractSitemap
>> {
>>
>>     @Override
>>     public void configure()
>>     {
>>        when( "linkmap.xml" )
>>                  .newCachingPipeline()
>>                  .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
>>                  .addComponent( new
>> XSLTTransformer(this.getClass().getResource("/trax.xslt") )
>>                  .setFinisher( XMLSerializer.createXMLSerializer );
>>
>>         ...
>>
>>        when( "linkmap2.xml" )
>>                  .newCachingPipeline()
>>                  .setStarter( new XMLGenerator(new URL( "feed2.xml" ) )
>>                  .addComponent( new
>> XSLTTransformer(this.getClass().getResource("/trax2.xslt") )
>>                  .setFinisher( XMLSerializer.createXMLSerializer );
>>
>>         ...
>>     }
>>
>> }
>> +-------------------------+
>>
>> we could also work by Sitemap composition:
>>
>>
>> +-------------------------+
>> public class MySitemap
>>     implements Sitemap
>> {
>>
>>     public void configure( SitemapBinder binder )
>>     {
>>         binder.when( "linkmap.xml" )
>>                  .newCachingPipeline()
>>                  .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
>>                  .addComponent( new
>> XSLTTransformer(this.getClass().getResource("/trax.xslt") )
>>                  .setFinisher( XMLSerializer.createXMLSerializer );
>>
>>         ...
>>
>>         binder.include( new MySitemap2() );
>>
>>         ...
>>     }
>>
>> }
>> +-------------------------+
>>
>> then a special loader is used to create the application:
>>
>> +-------------------------+
>> SitemapLoader.load( Sitemap...sitemaps );
>> +-------------------------+
>>
>> WDYT?
>> TIA, all the best,
>> -Simo
>>
>> http://people.apache.org/~simonetripodi/
>> http://www.99soft.org/
>
>

Re: [Discuss] Sitemap NG

Posted by Peter Hunsberger <pe...@gmail.com>.
Hi Simone,

long time ago we had discussions on alternate languages for the C2 Sitemap,
I used to want to do them in XSLT (as opposed to XML) with Java extensions
to implement the actual interface from the XSLT to the resulting Cocoon
object tree for the sitemap. These days I sometimes wonder if I could build
sitemaps in Neo4J and have Cocoon read them in via it's Neo4Js REST
interface (or more directly)...

In some ways it seems Cocoon 3 is already aimed at  most of what you
outline or is this in addition to the way you can do Java pipelines there?

Peter Hunsberger


On Mon, Aug 6, 2012 at 2:50 AM, Simone Tripodi <si...@apache.org>wrote:

> Hi all guys,
>
> I've had this mail draft for a long while and I think it's time to
> shout it out to get your feedbacks.
>
> Due to my involvement in Apache Commons and being strongly influenced
> by the Google-Guice design, I think we could get benefit from a vision
> that mixes the power of:
>
>  * modularity;
>  * Embedded DSL.
>
> The current situation is that the sitemap takes tons of Kb of Spring
> dependencies (please assume I'm not a big fan of Spring so my POV is
> influenced :P) and the sitemap is described via XML. Since we can
> still take the XML configuration, I'm sure - but I haven't had the
> time to write even a kickoff spike, so I still don't have the proof on
> hands - we could simplify the foundation of sitemap design, getting
> benefits from the javac using directly the Java language to describe
> the sitemap.
>
> What I'd suggest is introducing Sitemap(s) to describe how  the
> sitemap is organized, i.e.
>
> +-------------------------+
> interface Sitemap
> {
>
>     void configure( SitemapBinder binder );
>
> }
> +-------------------------+
>
> where the {{SitemapBinder}} contains a set of APIs to allow describing
> the path-matching;  a possible case could be:
>
> +-------------------------+
> public class MySitemap
>     implements Sitemap
> {
>
>     public void configure( SitemapBinder binder )
>     {
>         binder.when( "linkmap.xml" )
>                  .newCachingPipeline()
>                  .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
>                  .addComponent( new
> XSLTTransformer(this.getClass().getResource("/trax.xslt") )
>                  .setFinisher( XMLSerializer.createXMLSerializer );
>
>         ...
>
>         binder.when( "linkmap2.xml" )
>                  .newCachingPipeline()
>                  .setStarter( new XMLGenerator(new URL( "feed2.xml" ) )
>                  .addComponent( new
> XSLTTransformer(this.getClass().getResource("/trax2.xslt") )
>                  .setFinisher( XMLSerializer.createXMLSerializer );
>
>         ...
>     }
>
> }
> +-------------------------+
>
> that would reflect what in XML would be expressed as:
>
> +-------------------------+
> <map:match pattern="linkmap.xml">
>   <map:generate src="classpath:feed" />
>   <map:transform src="{lm:transform.linkmap.document}"/>
>   <map:serialize type="xml" />
> </map:match>
>
> ...
>
> <map:match pattern="linkmap2.xml">
>   <map:generate src="classpath:feed2" />
>   <map:transform src="{lm:transform.linkmap.document}"/>
>   <map:serialize type="xml" />
> </map:match>
>
> ...
> +-------------------------+
>
> of course, XML looks compact, but please take in consideration that
> XML is not type checking, we can get errors at runtime only; that
> means that a transformer can be erroneously set as generator, while
> using Java APIs it would be notified at compile time.
>
> An AbstractSitemap would help to reduce the `binder` variable verbose
> and redundant call:
>
>
> +-------------------------+
> public class MySitemap
>     extends AbstractSitemap
> {
>
>     @Override
>     public void configure()
>     {
>        when( "linkmap.xml" )
>                  .newCachingPipeline()
>                  .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
>                  .addComponent( new
> XSLTTransformer(this.getClass().getResource("/trax.xslt") )
>                  .setFinisher( XMLSerializer.createXMLSerializer );
>
>         ...
>
>        when( "linkmap2.xml" )
>                  .newCachingPipeline()
>                  .setStarter( new XMLGenerator(new URL( "feed2.xml" ) )
>                  .addComponent( new
> XSLTTransformer(this.getClass().getResource("/trax2.xslt") )
>                  .setFinisher( XMLSerializer.createXMLSerializer );
>
>         ...
>     }
>
> }
> +-------------------------+
>
> we could also work by Sitemap composition:
>
>
> +-------------------------+
> public class MySitemap
>     implements Sitemap
> {
>
>     public void configure( SitemapBinder binder )
>     {
>         binder.when( "linkmap.xml" )
>                  .newCachingPipeline()
>                  .setStarter( new XMLGenerator(new URL( "feed.xml" ) )
>                  .addComponent( new
> XSLTTransformer(this.getClass().getResource("/trax.xslt") )
>                  .setFinisher( XMLSerializer.createXMLSerializer );
>
>         ...
>
>         binder.include( new MySitemap2() );
>
>         ...
>     }
>
> }
> +-------------------------+
>
> then a special loader is used to create the application:
>
> +-------------------------+
> SitemapLoader.load( Sitemap...sitemaps );
> +-------------------------+
>
> WDYT?
> TIA, all the best,
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://www.99soft.org/
>