Return-Path: Delivered-To: apmail-cocoon-dev-archive@www.apache.org Received: (qmail 76115 invoked from network); 4 Mar 2009 23:33:38 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 4 Mar 2009 23:33:38 -0000 Received: (qmail 68231 invoked by uid 500); 4 Mar 2009 23:33:37 -0000 Delivered-To: apmail-cocoon-dev-archive@cocoon.apache.org Received: (qmail 68161 invoked by uid 500); 4 Mar 2009 23:33:37 -0000 Mailing-List: contact dev-help@cocoon.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@cocoon.apache.org List-Id: Delivered-To: mailing list dev@cocoon.apache.org Received: (qmail 68152 invoked by uid 99); 4 Mar 2009 23:33:37 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 04 Mar 2009 15:33:37 -0800 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of grek@tuffmail.com designates 216.86.168.183 as permitted sender) Received: from [216.86.168.183] (HELO mxout-08.mxes.net) (216.86.168.183) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 04 Mar 2009 23:33:26 +0000 Received: from [192.168.0.125] (unknown [82.210.157.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.mxes.net (Postfix) with ESMTPSA id 7E166D05AE for ; Wed, 4 Mar 2009 18:33:04 -0500 (EST) Message-ID: <49AF0FB6.1090103@tuffmail.com> Date: Thu, 05 Mar 2009 00:33:10 +0100 From: Grzegorz Kossakowski User-Agent: Thunderbird 2.0.0.19 (X11/20081227) MIME-Version: 1.0 To: Cocoon's dev mailing list Subject: [C3] Sitemap implemented in Scala Content-Type: text/plain; charset=ISO-8859-2 Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org 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