Saturday, 23 June 2007

Modeling Generics With XML Schema

Are you feeling curious today? I'll bet you are!



With the introduction of generics to Ecore itself we needed to think about keeping our round trip stories complete so there was a little bit of last minute scrambling to complete the support to make Ecore -> XML Schema -> Ecore and Ecore -> Java -> Ecore both continue to be round trips for all the new constructs we've added.

This schema shows that it's now possible to define your complex types as normal, and to specify their type arguments as well, kind of like having your cake and eating it too:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
xmlns:tree="http:/www.example.org/tree"
ecore:nsPrefix="tree"
ecore:package="org.example.tree"
targetNamespace="http:/www.example.org/tree">
<xsd:element name="Node" type="tree:Node"/>
<xsd:complexType name="Node">
<xsd:annotation>
<xsd:appinfo
ecore:key="typeParameters"
source="http://www.eclipse.org/emf/2002/Ecore">
<typeParameter name="T"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element
ecore:keys="label"
ecore:opposite="parent"
ecore:type="tree:Node{T}"
maxOccurs="unbounded"
minOccurs="0"
name="children"
type="tree:Node"/>
</xsd:sequence>
<xsd:attribute
ecore:reference="T"
name="data"
type="xsd:anyURI"/>
<xsd:attribute
name="label"
type="xsd:string"/>
<xsd:attribute
ecore:opposite="children"
ecore:reference="tree:Node{T}"
name="parent"
type="xsd:anyURI"/>
</xsd:complexType>
</xsd:schema>

Notice that we use {} as synonyms for <>, since the later requires the use of entities in the XML representation, which tends to make the results quite unreadable. By hey, is XML actually designed to be human readable, or does it favor the machine? Given that a < within quotes could be handled unescaped by a machine without much challenge and yet must be escape to make it even easier for the machine, I'd argue that XML is sadly twisted in favor of the machine.

Converting this XML Schema to Ecore produces this model, which records as EAnnotations just enough information about the schema so that instances can be serialized to conform to it:



Generating the Java for this Ecore model produces the following, which records as @model annotations just enough information to be able to recover the original Ecore model

package org.example.tree;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;

/**
* @model extendedMetaData="name='Node' kind='elementOnly'"
*/
public interface Node<T> extends EObject
{
/**
* @model opposite="parent" containment="true" keys="label"
* extendedMetaData="kind='element' name='children'"
*/
EList<Node<T>> getChildren();

/**
* @model kind="reference"
* extendedMetaData="kind='attribute' name='data'"
*/
T getData();
void setData(T value);

/**
* @model dataType="org.eclipse.emf.ecore.xml.type.String"
* extendedMetaData="kind='attribute' name='label'"
*/
String getLabel();
void setLabel(String value);

/**
* @model opposite="children" transient="false"
* extendedMetaData="kind='attribute' name='parent'"
*/
Node<T> getParent();
void setParent(Node<T> value);
}


Given the above Java, we can reproduce the originating Ecore and from that we can export the original schema. So in this case, even XML Schema -> Ecore -> Java -> Ecore -> XML Schema is a round trip. The value of this lies in the fact that any of these different forms of the same model can be your starting point and any of the others can be produced from it. Ecore is like the hub in a hub-and-spoke transportation system; every time another two-way spoke is added to the hub, everyone benefits. The UML project provides Ecore importers and exporters to support its own spoke and so the network grows...

It's clear that Ecore, XML Schema, UML, and Java are very different things, but the really useful insight is to see their similarities and then to use those similarities to build tools and runtimes that capitalize on them...

Sunday, 10 June 2007

Stop and Smell the Flowers

When the garden is this lovely:


It's time to stop and smell the flowers:


Often it seems there isn't nearly enough time for the important things in life.

Saturday, 2 June 2007

Sneaky Behavior?

This year we started feeding the foxes that regularly visit our back yard, hoping they'll be so well fed, they won't be tempted to eat our dogs. It's very hard to get a picture of these sneaky little guys in action, so we bought a motion triggered camera. The picture quality isn't great, but look who we caught red pawed at the trough:


It turns out there are actually two of these little guys!


And a big one too.


We think the little ones are the babies from last year and are hoping to see new babies from this year out and about soon.

Speaking of apparent sneaky behavior. When the JDJ polls for best Java component closed the other day, I was rather pleased to see that EJB3 was at 583, JSuite at 593, and EMF at 623. Imagine my surprise when the next day the standing was quite different. Despite the polls being closed, JSuite had jumped to 746. That's a surge of 153 votes all in one day. That's quite the voter turnout, especially after the polls were closed! If I'd had my little camera set up at the ballot box, we'd get some really interesting pictures. I'm hopeful that the JDJ auditing process will take note of such irregularities..