28 January 2009

Use XSLT to create a nice table in text

XSLT is a nice mechanism to transform a XML data file into something else. I had a case when I was to export some "messages" from a software to text and HTML. XSLT can perform both if the data source is an XML file. If you have the data as Java object JAXB can be used to convert Java objects to XML.

Lets say you have this XML file with a custom made format:
<messages>
<message>
<parameter name="Time">16:25:21.005</parameter>
<parameter name="Protocol">SIP</parameter>
<parameter name="Msg Size">376 byte(s)</parameter>
</message>
<message>
<parameter name="Time">16:25:21.015</parameter>
<parameter name="Protocol">SIP</parameter>
<parameter name="Msg Size">296 byte(s)</parameter>
</message>
<message>
<parameter name="Time">08:14:55.353</parameter>
<parameter name="Protocol">ISUP ITU</parameter>
<parameter name="Msg Size">59 byte(s)</parameter>
</message>
</messages>


This is the XSLT file to produce a nice text based table output:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<xsl:output method="text" />

<xsl:template match="/messages">
<xsl:call-template name="tab" />
<!-- The parameter name are extracted from the first message -->
<xsl:for-each select="message[1]/parameter">
<xsl:value-of select="@name" />
<xsl:call-template name="tab" />
</xsl:for-each>
<xsl:call-template name="newline" />

<xsl:for-each select="message">
<xsl:text>Message #</xsl:text>
<xsl:value-of select="position()" />
<xsl:call-template name="tab" />
<xsl:for-each select="parameter">
<xsl:value-of select="." />
<xsl:call-template name="tab" />
</xsl:for-each>
<xsl:call-template name="newline" />
</xsl:for-each>
</xsl:template>

<xsl:template name="newline">
<xsl:text>&#10;</xsl:text>
</xsl:template>

<xsl:template name="tab">
<xsl:text>&#9;</xsl:text>
</xsl:template>

</xsl:stylesheet>


Sun Java 6 SE has build in XSLT support version 1.0. Please note that XSLT version 2.0 contains some new features. If you wish to use these you must plugin an external XSLT enginge (probably not that hard).

Use this Java code to transform:
package se.lesc.blog.xsltexample;

import java.io.StringWriter;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class TransformExample1 {

public TransformExample1() throws TransformerException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer;
transformer = transformerFactory.newTransformer(new StreamSource(getClass()
.getResourceAsStream("messageTable.xsl")));

StringWriter text = new StringWriter();

transformer.transform(new StreamSource(getClass().getResourceAsStream("messages.xml")),
new StreamResult(text));
System.out.println(text);
}

public static void main(String[] args) throws TransformerException {
new TransformExample1();
}
}

It will produce this output:
 Time Protocol Msg Size 
Message #1 16:25:21.005 SIP 376 byte(s)
Message #2 16:25:21.015 SIP 296 byte(s)
Message #3 08:14:55.353 ISUP ITU 59 byte(s)

16 January 2009

JAXB to map Java objects to XML

JAXB is a java object to XML mapping framework. It makes it rather easy to convert Java objects to and from XML. I've previously used Java DOM trees to create and write XML or XPath expressions when only reading XML.

There are two approaches in to code JABX:
  1. Start with Java objects
  2. Start with XML definition (typically an XML schema)
If you would like to go for the second approach you create a XML Schema file mySchema.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.lesc.se/blog/test/mySchemaV1.0"
xmlns:tns="http://www.lesc.se/blog/test/mySchemaV1.0"
elementFormDefault="qualified">

<element name="persons">
<complexType>
<sequence>
<element name="person" maxOccurs="unbounded" minOccurs="0">
<complexType>
<sequence>
<element name="name" type="string" />
<element name="age" type="int" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>

Then run this the xjc command (it is included in the JDK installation in the bin-directory) to generate Java classes:
xjc mySchema.xsd
I like to start with the Java objects since I'm a programmer and like to have control over the Java code. To do this create the Java objects and annotate the class. For example like this:
package se.lesc.blog.test.myschemav1;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
@XmlRootElement(name = "persons")
public class Persons {

@XmlElement(name = "person")
protected List<Persons.Person> persons = new LinkedList<Persons.Person>();

public List<Persons.Person> getPersons() {
return persons;
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
public static class Person {

protected String name;
protected int age;

public String getName() {
return name;
}

public void setName(String value) {
this.name = value;
}

public int getAge() {
return age;
}

public void setAge(int value) {
this.age = value;
}
}
}

You then need to make JAXB aware of the two classes you've created in special file jaxb.index:
Persons
Persons$Person
You also need a package annotation (package-info.java):
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.lesc.se/blog/test/mySchemaV1.0", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package se.lesc.blog.test.myschemav1;
Then it is easy to produce XML from this:
//Set up your model
Persons persons = new Persons();
Person someOne = new Person();
someOne.setName("A name");
someOne.setAge(40);
persons.getPersons().add(someOne);

JAXBContext jaxbContext = JAXBContext.newInstance("se.lesc.blog.test.myschemav1");
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(persons, System.out);
Or you can read from XML back into java objects:
String xml = "<?xml.... your xml here";
StringReader xmlReader = new StringReader(xml);
JAXBContext jaxbContext = JAXBContext.newInstance("se.lesc.blog.test.myschemav");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Persons persons = (Persons) unmarshaller.unmarshal(xml);

12 January 2009

How source code should not be organized

I'm a bit fascinated on how source code are organized in a repository. There are certainly different ways of doing it and there are many ways that are wrong, or at least clumsy. Here are some examples that I have seen in real life and hope that you don't make the same mistake.

The root as the java package root.
That is if you have a class named com.mycompany.MyClass the structure is
/com/mycompany/MyClass.java
Why is this wrong? This is ok if your repository only contains java source code. But I have never seen this happen. A repository always contain other files (build scriptes, resources, source code from other language etc). Putting the java pacakges root as the folder root will cause problem with include/exclude filters in build scripts and IDE:s. It will also make submodules hard to implement.

A better way is to put the source code in a dedicated directory. For example:
/src/java/main/ or just /src/main if you are absolutly sure that java is the programming language. So why not just /src? Well mainly becouse there are different types of source code. There are production source code, test source code and possibly more types. Even if you are only programming java there is justification for the /src/java/main, sometimes you will for example need to include java-like things (for example Google Web Toolkit is almost java, but not built the same).

Dependencies between modules not exposed in a development environment
Lets say you have your main module A. One of the developers begins to develop module B depenent of module A in a seperate repository path and not exposing this in a development environment. Developers in module A will not see the dependecies to module B. A change in module A could break module B without anyone knowing.

A better way is to have common workspace base containing both module A and B. this way all developers will check out all code and developers will get faster feedback. Maven has native support for this type of modularisation (and submodularisation).

08 January 2009

How to avoid tearing problems in Windows XP

I bought a new TV because I wanted to watch downloaded movies in HD quality. (My old TV was a 21 inch CRT (fat) TV).

My hardware/software setup is:
  • Windows XP
  • Media Player Classic Homecinema (same as Media Player Classic, but with better support for subtitles and some more features)
  • Nvidia Geforce 8600GT, using the 24Hz output, cloned display
  • Sony 40W4500 TV, 1080/24p input
  • One budget DVI to HDMI-cable (from grafics card to HDMI input 2 on the TV)

I soon saw that I had tearing problems. So what is tearing? It is when the computer sends a new picture to the display while the drawing of the previous picture in not complete. I managed to take a screen shot of the tearing. I used Media Player Classic Homecinema tearing test feature (it is the two red lines). The two vertical red lines should be straight, but they aren't because of tearing.
As it turns out there is a bug/problem with Nvidia drivers affecting VMR9 over DVI when not running in "Direct3D fullscreen" (a special mode that all games run in) more info.

This problem is not visible in Vista, only XP. Vista uses this Direct3D fullscreen mode for its desktop, XP does not.

The solution to the problem is to change the renderer in Media Player Classic Homecinema to VMR7 ("System default" was not a option for me because I need subtitle support).

There are some new problems when using VMR7. It is more CPU instence. When I played a 1080p movie my Intel Core 2 Duo E8500 began dropping frames. To solve this problem I installed Core AVC codec. Now fewer frames are dropped and the playback is rather nice.