Hi gang,

(commons peeps, my first post here I think, did read http://jakarta.apache.org/commons/charter.html but couldn't find anything on mailing list conventions so hope all is ok)

read a few books on .net 'n stuff last week. Got me thinking again on metadata in the java world. I'm gonna throw an overview of various stuff out at y'all, along with some thoughts. Additions/corrections much needed I suspect ;)

----------------
.Net
----------------

.net stores metadata in compiled tables, basically mapping a reference (to a class, object, method, whatever) to a serialized representation of an attribute. An attribute is simply a serializable object extending a base Attribute class, very bean-like in nature.

In C#, you apply attributes to objects by placing the constructor for the attribute between square brackets, and optionally including a list of properties to set.

here's how'd might work in "Java.Net" pseudocode:

[Avalon.Attributes.Lifestyle("singlethreaded", poolable=true)]
class MyClass {}

[Avalon.Attributes.Lifestyle("threadsafe")]
class MyClass2 {}

would be preprocessed into something like:

class MyClass
{
static public Attributes[] _att;
static
{
_att = new Attributes[1];
_att[0] = new Avalon.Attributes.Lifestyle("singlethreaded");
_att[0].setPoolable(true);
}
}

class MyClass2
{
static public Attributes[] _att;
static
{
_att = new Attributes[1];
_att[0] = new Avalon.Attributes.Lifestyle("threadsafe");
}
}

and the _att stuff is then serialize()d and stored into a table, ie resulting in something like (in some hypothetical serialization format I just made up):

MyAssembly.jar!/META-INF/ClassMetaData.properties
-------------------------------------------------
MyClass.attributes=array:1:Avalon.Attributes.Lifestyle(f0:singlethreaded:f1:*:f2:1):
MyClass2.attributes=array:1:Avalon.Attributes.Lifestyle(f0:threadsafe:f1:*:f2:*):


When the class loads, the attributes are deserialized and are then easily accessible through introspection tools, ie you have something like

class AttributeUtil
{
public static boolean isSet(Object o,
String attributeName) { ... };
public static Attribute getAttribute(Object o,
String attributeName ) { ... };
}

There's more to it of course (for example, if you leave out constructor argument and property info, you can leave off the (), and you can also often do without the full package spec), but the basic idea is simple enough.

----------------
Avalon
----------------

As putting [] in your sourcefiles is a bit troublesome (most editors won't cope, for one), Pete (or someone else, doesn't matter, but he was the first to commit some code dealing with this that I saw) had the bright and obvious idea some time ago to put the metadata in the javadoc comments instead, ie the modified example becomes:

/**
* @attribute Avalon.Attributes.Lifestyle("singlethreaded",
* poolable=true)
*/
class MyClass {}

/**
* @attribute Avalon.Attributes.Lifestyle("threadsafe")
*/
class MyClass2 {}

and as it is somewhat cumbersome to do actual preprocessing, the idea was to just store the metadata information somewhere well-known (where the utility classes would know how to find it). So instead of

MyAssembly.jar!/META-INF/ClassMetaData.properties
-------------------------------------------------
MyClass.attributes=array:1:Avalon.Attributes.Lifestyle(f0:singlethreaded:f1:*:f2:1):
MyClass2.attributes=array:1:Avalon.Attributes.Lifestyle(f0:threadsafe:f1:*:f2:*):

what we get is:

MyAssembly.jar!/MyClass.xinfo
-----------------------------
<Attributes>
<Lifestyle type="singlethreaded">
<poolable value="true"/>
</Lifestyle>
</Attributes>

MyAssembly.jar!/MyClass2.xinfo
------------------------------
<Attributes>
<Lifestyle type="threadsafe"/>
</Attributes>

So far so good. Of course, with a verbose xml format for storing the metadata information, it is also possible to edit and maintain the xml files by hand.

There's one big difference though: with .Net, basically their designers figured out a compact way to specify the metadata by closely tying their semantics to objects. The way we're going now, with the metadata dtds, we loose some compactness, but more importantly the close ties are gone. "Custom metadata" is more difficult with the avalon setup.

(note: none of the above actually works; it's just pseudocode examples)
------------------
Commons Attributes
------------------

Commons Attributes (which I just took a first look at) is more similar to the .Net setup. It also uses QDox for parsing, but instead of defining some xml scheme, simply stores a serialized properties file. This is neat and simple (there's very little code neccessary to make it all work, the attribute parsing being handled by QDox).

Commons Attributes atm doesn't define a standard location to store attribute properties, nor does it contain code to automatically load the properties from that location and construct metadata object from them.

There's also less possibility for more complex setups than with the .Net way, as an attribute is a name/value pair rather than a potentially complex object.

----------------
Commons Clazz
----------------


Then there's Commons Clazz, which does a lot more, full of reflection tools and the like. There's also the idea within Clazz to support metadata, I'm not quite sure where they're at just yet. No website available yet, the only docs are @ http://cvs.apache.org/viewcvs.cgi/*checkout*/jakarta-commons-sandbox/clazz/PROPOSAL.html?rev=1.2

As there's less docs I have less of an opinion on Clazz, but it looks complex to me.

----------------
QDox, XDoclet
----------------

The QDox and XDoclet folks are also working on metadata stuff themselves I believe. Haven't looked at it much, but wanna. I'd say it'd be best to seperate the javadoc parsing from the metadata semantics.

---------------------
So which way forward?
---------------------

I'm currently thinking about which way to go with avalon re: all this. I'm still liking the approach taken in .net/C# the most.

I think a way forward might be to only so slightly extend Commons Attributes to support the "constructor-with-property", or basically the GlorifiedHashMap, along with defining a common location for metadata to be stored in jar files, and along with an avalon container that handles the reading writing of that data and automatically loads it for all managed components.

I'm not liking the complexity and size of Clazz very much atm (for dealing with this metadata thing that is; I think it'll be good at accomplishing its primary goal of reflection done right).

Avalon peeps, I think a good place to work on the basics is Jakarta Commons; what we need first is some utility code for constructing and destructing metadata, the IoC specifics 'n stuff can come later. With gmane setup, it is no longer neccessary to subscribe to yet-another-gazillion-messages-a-day list :D


cheers all,

- Leo




--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to