Oliver Kiessler wrote:
hi sandro,
the basic idea is, to use the bean class structure as the master and create the nodetypes according to the bean classes. E.g it could be possible to create the beans out of an uml tool. At the moment I can imagine the following use cases: a) creating the nodetype structure at design time b) reading beans from nodes at runtime c) writing beans to nodes at runtime d) persist beans to the persistance layer e) maintaining the bean structure (rename beans or properties, delete beans or properties, change the type of the bean or property...)
I have been using java reflection to analyse class structure at
runtime (b, c, d). The class has to conform to the java bean
specification (private properties, getters and setters). The class has
to have a no-arg constructor and getters and setters. All primitives,
primitive arrays, java bean arrays, collections (Set, Map, List),
hashtables and vectors are currently supported.
First I would like to create a textual mapping between JCR features and Java features like: Mixin = Interface Node Type Name = Class Name isMixin = this.getClass().isInterface()
You should not be using mixins to do this in my mind. Mixins are special node attributes defining the nature of the *node* (rathing than the content) used by the JCR implementation (like mix:referenceable or mix:versionable). You should rather define custom node types do this if even necessary. The JCR is a CMS infrastructure that can be persisted in many different ways with exchangeablity and portability in mind. Using too many custom features may leave you with a repo that cannot be used by some JCR implementations.
Regarding (mixin == Interface || mixin != Interface): Chapter 6.7.4 Primary and Mixin Node Types: >In a JCR repository, every node has one and only one primary node >type. This node type defines, as mentioned, a set of restrictions on >the child items of the node. Like in Java - a class can only have one super class tree.
>In addition to its single primary node type, a node may also have >any number of mixin node types assigned to it. A mixin type is >similar to a primary type in that its definition has the same >parameters. It differs, though, in that it provides additional features >to a node, beyond those defined in the node type proper. Similar to Java - a class may have an interface.
>Furthermore, while a primary node type can be Âinstantiated as a >node (i.e., that nodeÂs structure is fully defined by its primary node >type) this is not the case with mixin types. A mixin type cannot >serve, by itself, to define the structure of a node; it just adds >properties and child node requirements to a node that already has a >primary node type. A mixin is not instantiatable and it adds just requirements for a node. For me this sounds like an interface.
>A particular supported node type is either a primary type or a mixin >type; it cannot be both. Like in Java - there is no entity that is both, a class and an interface.
> portability in mind. Using too many custom features may leave you with > a repo that cannot be used by some JCR implementations. I think only assigning a mixin feature is part of the level 2.
Like I said in my previous mail I would like to be more type safe e.g. to make it easier to read the content (e.g. in Day's Content Explorer). But don't mind, as I not yet have enough arguments for it ;-).
The way I do it, I create a content node at a certain path URI. This is the top level content node of standard type nt:unstructured containing a class property of the object that needs to stored. Then a subnode jcr:content is created. Primitives are stored in this node. For every complex type a new subnode is created containing the class property of the complex type. This is pretty much a big recursion.... Please have a look at the code for more details.
Also check out the spec 0.16.2: chapter 6.7.4, 6.7.19.1, 6.7.21
some initial ideas: a) Maybe we can use the Struts bean introspection to check the beans, create the nodetypes out of that information and registering them. Too bad, that creation and registering of nodetypes is not part of the JCR-spec :-(.
I don't believe nodes are intended to represent a java bean object.
Why do you think that's the case?
Yes you are right. This is maybe a performance problem when converting the two types.
b) With bean class name equals node type name and bean property name equals child node name or property name it should be possible to use the JCR introspection to get the node values. Maybe we can provide the data by a generic Object getProperty(Object beanObject, String propertyName); method.
Please have a look at 6.2.5 of the spec. You can definately reflect on a jcr node property but not all java primitives are supported by the jcr, for instance int, byte and short are not available. You have to use long instead.
Hmm. Maybe we have different philosophies for the mapping. I had not something like a plain byte stream in my mind. But of course - your way would be easier to implement.
What do you think about all this?
I think your ideas are very interesting. Mapping java bean objects to a JCR is a very common usecase (of the future...). Creating a framework for serializing these objects into a JCR at runtime is the way to go in my mind. Please let me know what you think about this.
Regards,
Sandro
regards, oliver
