cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Grzegorz Kossakowski <>
Subject [C3] Sitemap implemented in Scala
Date Wed, 04 Mar 2009 23:33:10 GMT

I've just finished first phase of my work to implement sitemap in Scala.

There were couple reasons why I started this work:
  1. I wasn't satisfied with current implementation that seemed to me rather hard to follow.
Still it looks much better
than what we have in 2.2.
  2. I wanted to try Scala-Java integration in real world scenario.
  3. I wanted to find out if Scala code can be *easily* integrated into existing code-base
  4. I had an idea how to implement sitemap processing in quite different way and I wanted
to find out what I'll come up
with eventually.

So here it comes:
It's a branch out of our existing trunk found in svn. The only affected module is cocoon-sitemap.

Now I'll describe briefly why my implementation is different. Apart from obvious thing that
I have used different
language (Scala instead of Java) there are some more interesting things about it.

The first thing that is rather apparent to anyone looking at this implementation that it's
not OO-based. I don't want to
go into details why I think OO does not make much sense for sitemap processing right now.
This implies that (at least in
current form) sitemap language cannot be extended in a way one can do in original C3's implementation.
Anyway, I find
this functionality barely useful so I didn't bother myself to make it working with my code
even if I think it would be

All classes representing sitemap nodes are simple case classes defined in SitemapNode.scala[1].
Think of case classes as
java beans on steroids grouped into set of distinct and well defined cases.

The class responsible for parsing sitemap xml and producing it's representation is SitemapBuilder[2].
I suggest to you
to skim over the code as there are couple of interesting things involved like pattern matching
and xml literals. Mixing
XML with the code may resemble XSP but I believe this is really a different case.

Next step of sitemap processing is reduction. Sitemap tree reduction is defined as traversing
the tree and erasing all
conditional nodes like map:match and map:select. The result of reduction is a list of components
(either actions or
pipeline components) that were contained in conditional nodes that have their condition satisfied.
Every component is
accompanied by list of error handler applicable to the scope that given component is defined
The class SitemapReductor[3] is responsible for sitemap reduction. This class shows[4] how
one can easily and almost
seamlessly call Java code from Scala. The only glitch is that "match" is keyword in scala
but apart from that calling
Java code does not differ in any way from calling Scala code.

The last step of sitemap processing is invoking the result of the reduction. It's SitemapInvoker[5]
class that is
responsible for that. This class is only partly implemented as I didn't have time to deal
with component factories
needed to build actions and pipeline for execution. Anyway, this class extracts two distinct
sets of nodes that we are
interested in:
  * actions
  * pipeline components

>From this point, building a pipeline and executing actions is rather trivial task.

                                                                      -- o0o --

That's the big picture of the implementation. Now I'll give a few words of comments why I
find my implementation easier
to follow. First of all, sitemap processing is divided into a few distinct stages:
  1. Sitemap parsing
  2. Sitemap reduction
  3. Sitemap invocation
     3.1 Actions execution
     3.2 Pipeline building
     3.3 Pipeline execution
     3.4 Catching possible exception
  4. If exception catched, reduction of handle errors node
  5. Handling exception with reduction result

What's more, for most of the time code is based on immutable structures which is the biggest
advantage. What I found
hard with current implementation hard is InvocationImpl passed around that quite a lot of
state. If you combine it with
InvocationResult switches (cases) that every node has to return in its invoke() method the
result isn't really
appealing. This sort of resembles mistakes from C2.x where big, mutable objects were passed
around leading to
unmaintainable code.

I'm interested in hearing your opinions on that subject. I know that's rather hard to judge
rather big piece of code in
unfamiliar language but I'm sure you can easily get some overall feeling about my implementation
and ideas behind it.

PS. You can download the snapshot from GitHub and compile it using Maven as Scala distributes
Maven compiler plug-in.
This proves that integration with existing Java code-base can be achieved very easily.

PS2. This code is just a first version. I see quite a lot of places where it could be made
more concise and more
readable but I don't have a time right now to polish it more.

Thanks for listening.


Best regards,
Grzegorz Kossakowski

View raw message