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
