First steps

Very basic example

Given the structure,

 <msgDb>
 	<message id="msg1" created="10.04.2003 13:12:32" author="me" version="1" >
		My message text
	</message>
	<message id="msg2" created="12.04.2003 18:45:22" author="me" version="2" >
		My second message text
	</message>	  		
</msgDb>
	  		

only this should be needed to read the xml contents:

XmlConverter converter = new XmlConverter(new <AnnotationStrategy>, new <ObjectStrategy>);
MsgDb root = converter.convert(<inputstream|source>, MsgDb.class);
System.out.println("# elements = " + root.getMessages().size());

Message.java and MsgDb.java are defined as follows (and will get improved along the way):

public interface Message
{
	public String getId();
	public String getCreated();
	public String getAuthor();
	public int getVersion();	
	public String getContent();
}			
			
and
import de.keepondreaming.xml.annotations.ReturnTypeAnnotation;

public interface MsgDb
{    
	@ReturnTypeAnnotation(genericClass=Message.class)
	public java.util.List<Message> getMessages();
}			
			
and a test driver:
import de.keepondreaming.xml.ProxyObjectStrategy;
import de.keepondreaming.xml.XmlConverter;
import de.keepondreaming.xml.annotations.JavaAnnotationsStrategy;

public class Driver
{
	public static void main(String[] args) throws Exception
	{
		XmlConverter converter = new XmlConverter(new JavaAnnotationsStrategy(), new ProxyObjectStrategy());
		MsgDb root = (MsgDb) converter.convert(Driver.class.getResourceAsStream("in.xml"), MsgDb.class);
		System.out.println("Content of msg2 is \"" + root.getMessages().get(1).getContent() + "\"");
	}
}
			

As you can see you had to annotate the method getMessages(), since the converter can not obtain the expected return types from the runtime information. Generics information is not stored, so declaring List<Message> getMessages() does not help at runtime.

You could also drop the annotation and use an annotation strategy using property files for the runtime information.

Improved example

If you were content with this you would be done. But there are ways to improve this:

  • Use the id of the messages as an access key
  • Return a creation date as a java.util.Date (or a subclass)
So ... this would be the improved version
import de.keepondreaming.xml.annotations.DateFormat;

public interface Message
{
	public String getId();
	@DateFormat(formatString="dd.MM.yyyy HH:mm:ss")
	public java.sql.Timestamp getCreated();
	public String getAuthor();
	public int getVersion();
	public String getContent();
}			
			
and
			
import de.keepondreaming.xml.annotations.ReturnTypeAnnotation;
import de.keepondreaming.xml.annotations.SetKeyAttribute;

public interface MsgDb
{
	@ReturnTypeAnnotation(genericClass=Message.class)
	@SetKeyAttribute(keyAttribute="id")    
	public java.util.Map<String, Message> getMessages();
}			
			
Now for the test driver, which shows the content of the first message with the key "msg1"
import de.keepondreaming.xml.ProxyObjectStrategy;
import de.keepondreaming.xml.XmlConverter;
import de.keepondreaming.xml.annotations.JavaAnnotationsStrategy;

public class Driver
{
	public static void main(String[] args) throws Exception
	{
		XmlConverter converter = new XmlConverter(new JavaAnnotationsStrategy(), new ProxyObjectStrategy());
		MsgDb root = (MsgDb) converter.convert(Driver.class.getResourceAsStream("in.xml"), MsgDb.class);
		System.out.println("Content of msg1 is \"" + root.getMessages().get("msg1").getContent() + "\"");
	}
}
			
Thats it. All in 20 kilobytes. For now.