The class as object phenomenon is actually quite pervasive, and I think it is 
possible to have a generalized solution for it.

After sending this email yesterday, I came up with a slightly different 
solution.

val taggable = namespace.getMetaClass("taggable", true)

val tagName = metaModelNamespace.getMetaProperty("tagname", true)
tagName.setCardinality(1)

val metaTaggable = metaModelNamespace.getMetaClass("taggable", true)
metaTaggable.getDirectProperties.add(tagName)
metaTaggable.getDirectInstances.add(taggable.node)

val body = namespace.getMetaClass("body", true)
taggable.getDirectSubs.add(body)

Instead of directly relating the class "body" to the meta class "taggable", I 
create a shadow of the meta class "taggable" with the same name in the 
namespace of the class "body", and make "body" a subclass of this shadow. That 
way the sub classing relationship remains nicely in one name space, while the 
instance relationship transcends name spaces, as it should. 

This could in principle be generalized by adding a methods to MetaModelClass:

public MetaModelClass createShadowClass(NameSpace ns){

    MetaModelClass mc = ns.getMetaClass(this.getName(), true);
    this.getDirectInstances.add(mc.node);
    return mc;
}

This returns a shadow of a given MetaModelClass in a given namespace and adds 
it as a an instance of this.

It would of course be nicer to have a method with the signature:

public MetaModelClass getShadow(NameSpace ns, Boolean create)

This is much more in line with the rest of the API, but requires a way to find 
out the namespace a given MetaModelClass is defined in. I didn't see a method 
getNamespace() for a given class, and didn't delve deeply enough in the source 
code to figure out how to do that. 

A similar approach can of course also be applied to MetaModelProperties, by 
adding the following method to MetaModelClass:

public MetaModelProperty 
createShadowProperty(NameSpace ns){



    MetaModelProperty mp = 
ns.getMetaProperty(this.getName(), true);

    
this.getDirectInstances.add(mp.node);

    return mp;

}


This way the underlying node of a MetaModelProperty can properly be used as a 
class of its own and have properties, relationships, that can be further 
modeled in the meta layer. This e.q. allows to set a default rendering format 
for a given property class.

I don't see a MetaModelRelationships, which is unfortunate, since that would 
allow the modeling of the properties of a Relationship.


Kind regards,
Niels Hoogeveen


> Date: Fri, 26 Mar 2010 11:26:29 +0100
> From: matt...@neotechnology.com
> To: user@lists.neo4j.org
> Subject: Re: [Neo] meta meta classes
> 
> That's an interresting case you've got here and it looks to me like it's
> probably the best way to model it in the meta model.
> 
> 2010/3/25 Niels Hoogeveen <pd_aficion...@hotmail.com>
> 
> >
> > For my application, I want to model an HTML template in Neo4J, using the
> > MetaModel api.
> >
> > So I started setting up MetaModelClasses for the various HTML entities.
> >
> > e.g. (code in Scala)
> >
> > val classProp = namespace.getMetaProperty("class", true)
> > val idProp =
> > namespace.getMetaProperty("id", true)
> > idProp.setCardinality(1)
> >
> >
> > val body = namespace.getMetaClass("body", true)
> > body.getDirectProperties(classProp)
> > body.getDirectProperties(idProp)
> >
> >
> > Which creates a class named "body" which has a property named "class"
> > without a cardinality restriction and a property named "id" with a
> > cardinality restriction of 1.
> >
> > Now I can create nodes of class "body" with various values for "class" and
> > for "id".
> >
> > So far so good, but now I want to say that the class body has a property
> > "tagname" which should get the value "body".
> >
> > The meta model itself doesn't allow classes to have properties, but it
> > allows access to the underlying node of the class.
> >
> > So I created a separate namespace for the meta meta classes and added the
> > following three definitions:
> >
> > val tagName = metaNamespace.getMetaProperty("tagname", true)
> > tagName.setCardinality(1)
> > val taggable = metaNamespace.getMetaClass("taggable", true)
> >
> > body.node.setProperty("tagname", "body")
> >
> > This creates a property "tagname" with the value "body" for the class named
> > "body".
> >
> > Now comes the more ambiguous part, how to link "body" to "taggable".
> >
> > I can make body.node an instance of taggable. Once there is a validator,
> > the existence of a "tagname" property with cardinality 1 should be checked,
> > so it is reasonable to make body.node an instance of taggable.
> >
> > At the same time the class body is actually a subclass of taggable, so I am
> > inclined to define that as well.
> >
> > So I end up doing the following:
> >
> > taggable.getDirectInstances.add(body.node)
> > taggable.getDirectSubs.add(body)
> >
> > I would like to know if this is the correct approach to this situation, or
> > whether there are better alternatives.
> >
> > Kind regards,
> > Niels Hoogeveen
> >
> >
> > _________________________________________________________________
> > New Windows 7: Find the right PC for you. Learn more.
> > http://windows.microsoft.com/shop
> > _______________________________________________
> > Neo mailing list
> > User@lists.neo4j.org
> > https://lists.neo4j.org/mailman/listinfo/user
> >
> 
> 
> 
> -- 
> Mattias Persson, [matt...@neotechnology.com]
> Neo Technology, www.neotechnology.com
> _______________________________________________
> Neo mailing list
> User@lists.neo4j.org
> https://lists.neo4j.org/mailman/listinfo/user
                                          
_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
_______________________________________________
Neo mailing list
User@lists.neo4j.org
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to