Hi,

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: 
http://github.com/gkossakowski/apache-cocoon3/tree/scalaSitemapEval
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
possible.

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 in.
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.

[1]
http://github.com/gkossakowski/apache-cocoon3/blob/b0b85d22cad801c90a33ad8c1a18d88b1c0d3244/cocoon-sitemap/src/main/scala/org/apache/cocoon/sitemap/node/sc/SitemapNode.scala
[2]
http://github.com/gkossakowski/apache-cocoon3/blob/b0b85d22cad801c90a33ad8c1a18d88b1c0d3244/cocoon-sitemap/src/main/scala/org/apache/cocoon/sitemap/sc/SitemapBuilder.scala
[3]
http://github.com/gkossakowski/apache-cocoon3/blob/b0b85d22cad801c90a33ad8c1a18d88b1c0d3244/cocoon-sitemap/src/main/scala/org/apache/cocoon/sitemap/sc/SitemapReductor.scala
[4]
http://github.com/gkossakowski/apache-cocoon3/blob/b0b85d22cad801c90a33ad8c1a18d88b1c0d3244/cocoon-sitemap/src/main/scala/org/apache/cocoon/sitemap/sc/SitemapReductor.scala#L145
[5]
http://github.com/gkossakowski/apache-cocoon3/blob/b0b85d22cad801c90a33ad8c1a18d88b1c0d3244/cocoon-sitemap/src/main/scala/org/apache/cocoon/sitemap/sc/SitemapInvoker.scala

-- 
Best regards,
Grzegorz Kossakowski

Reply via email to