If you're interested in functional programming, you might also want to checkout my second blog which i'm actively working on!!

Thursday, May 28, 2009

M2Eclipse plugin

The Maven2 plugin for eclipse is quite a relief for non-maven guru's. One cool feature is the Dependenc Graph which calculates all your project dependencies and plots them in a nice Graph. If you ever wondered how much dependencies a typical Cocoon2.2 block has, here you go ;-)

Problem setting M2_REPO variable in Eclipse Ganymede 3.4.2

I just installed the latest version of Eclipse and M2Eclipse pluging from Sonatype and apparently you get an out-of-the-box M2_REPO variable which you can't modify.

So Eclipse gave me warnings that my project was missing the required libraries. The issue was luckily easily resolved by copying the settings.xml from my Maven installation to C:\Documents and Settings\arobpel\.m2

Wednesday, May 27, 2009

Saxon isssue: java.lang.IllegalArgumentException: Unknown type of result: class > javax.xml.transform.dom.DOMResult

I created a cocoon2-2 block last week and everything seemed to work just fine using "mvn jetty:run". However, when deploying the complete war on tomcat I got following stacktrace:

java.lang.IllegalArgumentException: Unknown type of result: class javax.xml.transform.dom.DOMResult net.sf.saxon.event.SerializerFactory.getReceiver(SerializerFactory.java:154)

Googling around a bit I found out I needed to rename the saxon-8.7.jar to zsaxon-8.7.jar so this jar will be loaded last.

Explanation:
The problem happens because the saxon.jar contains API classes related to DOM Level 2. The xml-apis.jar contains API for DOM Level 3. Cocoon 2.1.8 was shipped with xerces 2.7.1 and xalan 2.7.0. Both needs DOM Level 3. Hence if in the classpath the saxon.jar is first, we get DOM Level 2 related classes and you got the problem as you showed up.



After upgrading to maven3 the above workaround did not work anymore so I advise you to use below approach and add a systemproperty to the maven-surefire-plugin

Tuesday, May 12, 2009

Creating Scalable Vector Graphics with Apache Cocoon

I've done some projects in the past where we created Scalable Vector Graphics. The nice thing about SVG is that you can scale the images without any quality loss. Back then, the only way to render SVG in the browser was by installing a plugin from Adobe. Now most browsers are able to render them without any plugins.

So how do you get started? This little tutorial assumes you have some basic Cocoon knowledge

Create a SVG template with the SVG editor of your choice.
Some suggestions:Replace the hardcoded values which should become parameters like this: ${logotext}











Below you will find some relevant sitemap.xmap snippets which i configured to create a dynamic image.















If we take a quick look at line 138, you see that when we invoke the url wich matches "generate/logo", the template "ciber/templates/logo.jx.xml" is read, the ${} values are replaced by their corresponding values if present and the svg-template is serialized to jpeg.

We only need some way to fill that missing ${logotext} parameter. Cocoon offers flowscript to the rescue. Flowscript is plain javascript in which you can write the controller which takes care of building the model which will be passed on to the view. (Model-View-Controller).

Our controller will use a sitemap parameter to fill in the missing ${logotext}. In line 132, you see a match pattern "logo/*" where * is our first and only {1} parameter which we pass on to the flowscript function "createLogo" on line 134.

Let's take a quick look at our flowscript (logo.js)






When you invoke following URL:
"http://localhost:8888/cocoonDemo/logo/Creating SVG with Cocoon" the sitemap matches this on line 132. It call's the function createLogo() and passes it the sitemap parameter 'logotext' with value 'Creating SVG with Cocoon'.

On lines 2 and 3 we build a javascript object 'data' with a variable named logotext and pass it the value of the sitemap-parameter with the same name. On line 5 our controller tells cocoon to render a page by invoking the match pattern "generate/logo" and pass it our constructed model 'data'.

Now the sitemap matches line 138, but this time it does have a model containing a value for 'logotext'. Let's take a look at the end result.






This demo shows you the most basic (simple) case to create dynamic SVG. More difficult use cases are when you read in your data from a database or XML files and use this data in transformations to construct SVG.

Cheers,
Robby

Monday, May 11, 2009

Apache Cocoon 3: sitemap support for xml validation

I just checked out the still in alpha-1 phase Cocoon3 from trunk. One thing that immediately catched my eye when browsing the cocoon-3 sample block is the support for validation which I kinda missed in previous versions.

It's a matter of adding a transformer of type "schema" in your sitemap.

<map:transform type="schema" src="sax-pipeline/simple.xsd" />


Cool stuff !!
Robby

Friday, May 8, 2009

Calculating rowspan for cellmerging

Ok... Here is a small demo that shows you a way how to calculate the rowspan.

contacts.xml will be the starting point for this exercise.




















In a first step we do a little xml to xhtml conversion in order to view our data in a table.

contacts2html.xslt:





















The result is the following:










Now suppose we want to merge cell's in the city column.

mergecells.xslt snippet:












The final output looks like this:











This demo shows you it's quite easy to calculate the rowspan using the 'deep-equal' function recursively.

Cheers,
Robby

Thursday, May 7, 2009

comparing nodes with XSLT

Sometimes you want to compare xml nodes for equality. In case of equality you want let's say consequent rows to be spanned. Xpath provides a nice function for this use case:

http://www.w3.org/TR/xpath-functions/#func-deep-equal

Below you will find a testcase (input, xslt and output).

Input.xml













XSLT
















Output.xml