You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by Giota Karadimitriou <Gi...@eurodyn.com> on 2005/12/13 14:38:52 UTC

extend a node type

I am trying to extend the node type "nt:resource" in order to be able to add
custom properties to it.
I started by creating a new node type named my:myresource where 'my' is a
registered namespace. I also set the new node type to have a supertype of
"nt:resource".
However, I ran into the following problems:

1) Even though the new node type has "nt:resource" as a supertype as I mentioned
earlier, it does not automatically inherit any of its properties
(jcr:data,jcr:encoding,jcr:mimeType and jcr:lastModified). Maybe I am missing
sth but if the properties are not inherited, what is in fact inherited from a
certain supertype? As far as I can see properties are left out. So is it
children or is it sth else?

2)Since the properties were not inherited, I decided to find the properties of
nt:resource (PropDefs[]) and add them one by one to the new node type. I
therefore created a new PropDef array and I added all "nt:resource" properties
to it. I finally added an extra property "my:lang" to it. In the end, I assigned
this new PropDef array to the new node type. However, execution failed with
Exception 

org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException:
[{http://www.my.com/my/1.0}myresource#{http://www.jcp.org/jcr/1.0}encoding]
invalid declaring node type specified

	at
org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.validateNodeTypeDef
(NodeTypeRegistry.java:535)

	at
org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
(NodeTypeRegistry.java:1219)



This exception occured in validateNodeTypeDef method of NodeTypeRegistry class
in the sanity check part of the code where it checks the node type declaration
of the property


/**
             * sanity check:
             * make sure declaring node type matches name of node type definition
             */
            if (!name.equals(pd.getDeclaringNodeType())) {
                String msg = "[" + name + "#" + pd.getName()
                        + "] invalid declaring node type specified";
                log.debug(msg);
                throw new InvalidNodeTypeDefException(msg);
            } 

and the exception is thrown because 'name' = "my:resource" while
'pd.getDeclaringNodeType' = "nt:resource".
I think this is a bug because at this stage what should be checked is not
"equals" but also inheritance. What I mean is that maybe it should be also
checked whether 'pd.getDeclaringNodeType()' and 'name' have some other
connection besides equality, like inheritance for example; because
"my:myresource" is in fact nt:resource and in such a case, exception should not
be thrown

The way to implement what I just said would be to find the NodeTypeDef of 'name'
and the NodeTypeDef of 'pd.getDeclaringNodeType()' and check if the second is a
supertype of the first.

Of course maybe I am not heading towards the right direction here...but it is an
idea

3) Finally, to find a way arround the previous problem, I did the following:
Whenever I added an nt:resource property to the new node type; (e.g. when I
added jcr:data
to "my:myresource" propdef array) I also declared my:myresource as the declared
node type of the property using the following code (in order to avoid the
previous exception)

ws.getNamespaceRegistry().registerNamespace("my",
                "http://www.my.com/my/1.0");
QName mResourceName=new QName("http://www.my.com/my/1.0", "myresource");
((PropDefImpl)propDefsNew[i]).setDeclaringNodeType(mResourceName);

However this approach again failed with a new exception "Not implemented"

javax.jcr.RepositoryException: not yet implemented

	at
org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.checkForConflictingContent
(NodeTypeRegistry.java:1615)

	at
org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
(NodeTypeRegistry.java:1256)



Could anybody give me some feedback on the above issues or have any ideas how to
work arround them to extend a nt:resource node type?


 



Re: extend a node type

Posted by Peeter Piegaze <pe...@day.com>.
Hi Giota,

I see why you were confused: NodeTypeDef is an internal (i.e.,
non-JCR) Jackrabbit class that simply reflects the definition itself
without actually resolving that definition into a "live" node type by
assembling the property and child node defs inherited from supertypes.
To see the real node type you would use the JCR API NodeType
interface, which in Jackrabbit is implemented by NodeTypeImpl.

Cheers,
Peeter

On 12/13/05, Giota Karadimitriou <Gi...@eurodyn.com> wrote:
> Dear Peeter,
>
> thank you for you response. The reason I was claiming that the
> properties are not inherited and tried all those other solutions, was
> because when I used the code below to print the property definitions of
> the new node type, I was getting only 1 property (my:lang) and that is
> why I assumed no properties were inherited.
> However when I ignored these print statements and added jcr:data to a
> node of type my:resource it was added ok and Lucene search was able to
> search within it.
>
> Thank you for the information you provided and especially for pointing
> out the "autocreated" mechanism.
>
> Regards
> Giota
>
>
> QName mResourceName=new QName("http://www.my.com/my/1.0", "myresource");
> NodeTypeManager ntMgr=ws.getNodeTypeManager();
> NodeTypeRegistry
> ntReg=((NodeTypeManagerImpl)ntMgr).getNodeTypeRegistry();
>
>
> NodeTypeDef myResource=ntReg.getNodeTypeDef(mResourceName);
> PropDef[] propDefs=myResource.getPropertyDefs();
> System.out.println("myresource has::"+propDefs.length);
> for (int i=0; i<propDefs.length; i++){
>      System.out.println("PROP DEF:"+ propDefs[i].getName());
>  }
> QName superTypes[]=myResource.getSupertypes();
> for (int i=0; i<superTypes.length; i++){
>                 System.out.println("SUPER TYPE:"+
> superTypes[i].toString()+" "+superTypes[i].getLocalName());
> }
>
>
> >myresource has::1
> >PROP DEF:{http://www.my.com/my/1.0}lang
> > SUPER TYPE:{http://www.jcp.org/jcr/nt/1.0}resource resource
>
> -----Original Message-----
> From: peeter.piegaze@gmail.com [mailto:peeter.piegaze@gmail.com] On
> Behalf Of Peeter Piegaze
> Sent: Tuesday, December 13, 2005 5:11 PM
> To: jackrabbit-dev@incubator.apache.org
> Subject: Re: extend a node type
>
> Hi Giota,
>
> On 12/13/05, Giota Karadimitriou <Gi...@eurodyn.com>
> wrote:
> > I am trying to extend the node type "nt:resource" in order to be able
> to add
> > custom properties to it.
> > I started by creating a new node type named my:myresource where 'my'
> is a
> > registered namespace. I also set the new node type to have a supertype
> of
> > "nt:resource".
>
> This is correct.
>
> > However, I ran into the following problems:
> >
> > 1) Even though the new node type has "nt:resource" as a supertype as I
> mentioned
> > earlier, it does not automatically inherit any of its properties
> > (jcr:data,jcr:encoding,jcr:mimeType and jcr:lastModified). Maybe I am
> missing
> > sth but if the properties are not inherited, what is in fact inherited
> from a
> > certain supertype? As far as I can see properties are left out. So is
> it
> > children or is it sth else?
>
> Your new node type *does* inherit the property and child node
> definitions of its supertype (in this case nt:resource). For example,
> once you create and register your node type my:myresource you can
> query its characteristics through the methods of
> javax.jcr.nodetype.NodeType, and you will see that it has inherited
> the property definitions from nt:resource
>
> However, this does not mean that when you create a *new node* using
> my:myresource as the node type that these properties will
> automatically appear *on the node*. That only happens if the property
> or child node in question is defined as "autocreated".
>
> In the case of nt:resource, none of the properties are defined as
> autocreated so they do not appear automatically.
>
> What the node type does is define what properties are *allowed* to be
> added to the node --in the case of nt:resource, the prop jcr:encoding
> *may* be added-- and what properties *must* be added to the node, in
> this case, the other three: jcr:mimeType, jcr:data, and
> jcr:lastModified. Notice that these three are defined as "mandatory"
> (though not autocreated). This means you (the application) has to add
> them  before saving the node (otherwise the save will fail).
>
> Currently the best documentation on node types is the JSR 170 spec
> itself. There is an extensive chapter covering all these details...and
> more.
>
> Hope this helps,
> Peeter
>
> >
> > 2)Since the properties were not inherited, I decided to find the
> properties of
> > nt:resource (PropDefs[]) and add them one by one to the new node type.
> I
> > therefore created a new PropDef array and I added all "nt:resource"
> properties
> > to it. I finally added an extra property "my:lang" to it. In the end,
> I assigned
> > this new PropDef array to the new node type. However, execution failed
> with
> > Exception
> >
> > org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException:
> >
> [{http://www.my.com/my/1.0}myresource#{http://www.jcp.org/jcr/1.0}encodi
> ng]
> > invalid declaring node type specified
> >
> >         at
> >
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.validateNodeTypeDef
> > (NodeTypeRegistry.java:535)
> >
> >         at
> >
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
> > (NodeTypeRegistry.java:1219)
> >
> >
> >
> > This exception occured in validateNodeTypeDef method of
> NodeTypeRegistry class
> > in the sanity check part of the code where it checks the node type
> declaration
> > of the property
> >
> >
> > /**
> >              * sanity check:
> >              * make sure declaring node type matches name of node type
> definition
> >              */
> >             if (!name.equals(pd.getDeclaringNodeType())) {
> >                 String msg = "[" + name + "#" + pd.getName()
> >                         + "] invalid declaring node type specified";
> >                 log.debug(msg);
> >                 throw new InvalidNodeTypeDefException(msg);
> >             }
> >
> > and the exception is thrown because 'name' = "my:resource" while
> > 'pd.getDeclaringNodeType' = "nt:resource".
> > I think this is a bug because at this stage what should be checked is
> not
> > "equals" but also inheritance. What I mean is that maybe it should be
> also
> > checked whether 'pd.getDeclaringNodeType()' and 'name' have some other
> > connection besides equality, like inheritance for example; because
> > "my:myresource" is in fact nt:resource and in such a case, exception
> should not
> > be thrown
> >
> > The way to implement what I just said would be to find the NodeTypeDef
> of 'name'
> > and the NodeTypeDef of 'pd.getDeclaringNodeType()' and check if the
> second is a
> > supertype of the first.
> >
> > Of course maybe I am not heading towards the right direction
> here...but it is an
> > idea
> >
> > 3) Finally, to find a way arround the previous problem, I did the
> following:
> > Whenever I added an nt:resource property to the new node type; (e.g.
> when I
> > added jcr:data
> > to "my:myresource" propdef array) I also declared my:myresource as the
> declared
> > node type of the property using the following code (in order to avoid
> the
> > previous exception)
> >
> > ws.getNamespaceRegistry().registerNamespace("my",
> >                 "http://www.my.com/my/1.0");
> > QName mResourceName=new QName("http://www.my.com/my/1.0",
> "myresource");
> > ((PropDefImpl)propDefsNew[i]).setDeclaringNodeType(mResourceName);
> >
> > However this approach again failed with a new exception "Not
> implemented"
> >
> > javax.jcr.RepositoryException: not yet implemented
> >
> >         at
> >
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.checkForConflicting
> Content
> > (NodeTypeRegistry.java:1615)
> >
> >         at
> >
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
> > (NodeTypeRegistry.java:1256)
> >
> >
> >
> > Could anybody give me some feedback on the above issues or have any
> ideas how to
> > work arround them to extend a nt:resource node type?
> >
> >
> >
> >
> >
> >
>
>

Re: extend a node type

Posted by Stefan Guggisberg <st...@gmail.com>.
hi giota

you should try to avoid using jackrabbit classes directly in your application
but use the JCR api whenever possible. you only need to use
o.a.j.c.nodetype.NodeTypeRegistry if you want to register new node types.

if you were using javax.jcr.nodetype.NodeTypeManager in your code
sample the code would have been simpler and you would have gotten
the expected results:

NodeTypeManager ntMgr = ws.getNodeTypeManager();
NodeType nt = ntMgr.getNodeType("my:myresource");
PropertyDefinition[] pda = getPropertyDefinitions();
// etc etc

cheers
stefan

On 12/13/05, Giota Karadimitriou <Gi...@eurodyn.com> wrote:
> Dear Peeter,
>
> thank you for you response. The reason I was claiming that the
> properties are not inherited and tried all those other solutions, was
> because when I used the code below to print the property definitions of
> the new node type, I was getting only 1 property (my:lang) and that is
> why I assumed no properties were inherited.
> However when I ignored these print statements and added jcr:data to a
> node of type my:resource it was added ok and Lucene search was able to
> search within it.
>
> Thank you for the information you provided and especially for pointing
> out the "autocreated" mechanism.
>
> Regards
> Giota
>
>
> QName mResourceName=new QName("http://www.my.com/my/1.0", "myresource");
> NodeTypeManager ntMgr=ws.getNodeTypeManager();
> NodeTypeRegistry
> ntReg=((NodeTypeManagerImpl)ntMgr).getNodeTypeRegistry();
>
>
> NodeTypeDef myResource=ntReg.getNodeTypeDef(mResourceName);
> PropDef[] propDefs=myResource.getPropertyDefs();
> System.out.println("myresource has::"+propDefs.length);
> for (int i=0; i<propDefs.length; i++){
>      System.out.println("PROP DEF:"+ propDefs[i].getName());
>  }
> QName superTypes[]=myResource.getSupertypes();
> for (int i=0; i<superTypes.length; i++){
>                 System.out.println("SUPER TYPE:"+
> superTypes[i].toString()+" "+superTypes[i].getLocalName());
> }
>
>
> >myresource has::1
> >PROP DEF:{http://www.my.com/my/1.0}lang
> > SUPER TYPE:{http://www.jcp.org/jcr/nt/1.0}resource resource
>
> -----Original Message-----
> From: peeter.piegaze@gmail.com [mailto:peeter.piegaze@gmail.com] On
> Behalf Of Peeter Piegaze
> Sent: Tuesday, December 13, 2005 5:11 PM
> To: jackrabbit-dev@incubator.apache.org
> Subject: Re: extend a node type
>
> Hi Giota,
>
> On 12/13/05, Giota Karadimitriou <Gi...@eurodyn.com>
> wrote:
> > I am trying to extend the node type "nt:resource" in order to be able
> to add
> > custom properties to it.
> > I started by creating a new node type named my:myresource where 'my'
> is a
> > registered namespace. I also set the new node type to have a supertype
> of
> > "nt:resource".
>
> This is correct.
>
> > However, I ran into the following problems:
> >
> > 1) Even though the new node type has "nt:resource" as a supertype as I
> mentioned
> > earlier, it does not automatically inherit any of its properties
> > (jcr:data,jcr:encoding,jcr:mimeType and jcr:lastModified). Maybe I am
> missing
> > sth but if the properties are not inherited, what is in fact inherited
> from a
> > certain supertype? As far as I can see properties are left out. So is
> it
> > children or is it sth else?
>
> Your new node type *does* inherit the property and child node
> definitions of its supertype (in this case nt:resource). For example,
> once you create and register your node type my:myresource you can
> query its characteristics through the methods of
> javax.jcr.nodetype.NodeType, and you will see that it has inherited
> the property definitions from nt:resource
>
> However, this does not mean that when you create a *new node* using
> my:myresource as the node type that these properties will
> automatically appear *on the node*. That only happens if the property
> or child node in question is defined as "autocreated".
>
> In the case of nt:resource, none of the properties are defined as
> autocreated so they do not appear automatically.
>
> What the node type does is define what properties are *allowed* to be
> added to the node --in the case of nt:resource, the prop jcr:encoding
> *may* be added-- and what properties *must* be added to the node, in
> this case, the other three: jcr:mimeType, jcr:data, and
> jcr:lastModified. Notice that these three are defined as "mandatory"
> (though not autocreated). This means you (the application) has to add
> them  before saving the node (otherwise the save will fail).
>
> Currently the best documentation on node types is the JSR 170 spec
> itself. There is an extensive chapter covering all these details...and
> more.
>
> Hope this helps,
> Peeter
>
> >
> > 2)Since the properties were not inherited, I decided to find the
> properties of
> > nt:resource (PropDefs[]) and add them one by one to the new node type.
> I
> > therefore created a new PropDef array and I added all "nt:resource"
> properties
> > to it. I finally added an extra property "my:lang" to it. In the end,
> I assigned
> > this new PropDef array to the new node type. However, execution failed
> with
> > Exception
> >
> > org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException:
> >
> [{http://www.my.com/my/1.0}myresource#{http://www.jcp.org/jcr/1.0}encodi
> ng]
> > invalid declaring node type specified
> >
> >         at
> >
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.validateNodeTypeDef
> > (NodeTypeRegistry.java:535)
> >
> >         at
> >
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
> > (NodeTypeRegistry.java:1219)
> >
> >
> >
> > This exception occured in validateNodeTypeDef method of
> NodeTypeRegistry class
> > in the sanity check part of the code where it checks the node type
> declaration
> > of the property
> >
> >
> > /**
> >              * sanity check:
> >              * make sure declaring node type matches name of node type
> definition
> >              */
> >             if (!name.equals(pd.getDeclaringNodeType())) {
> >                 String msg = "[" + name + "#" + pd.getName()
> >                         + "] invalid declaring node type specified";
> >                 log.debug(msg);
> >                 throw new InvalidNodeTypeDefException(msg);
> >             }
> >
> > and the exception is thrown because 'name' = "my:resource" while
> > 'pd.getDeclaringNodeType' = "nt:resource".
> > I think this is a bug because at this stage what should be checked is
> not
> > "equals" but also inheritance. What I mean is that maybe it should be
> also
> > checked whether 'pd.getDeclaringNodeType()' and 'name' have some other
> > connection besides equality, like inheritance for example; because
> > "my:myresource" is in fact nt:resource and in such a case, exception
> should not
> > be thrown
> >
> > The way to implement what I just said would be to find the NodeTypeDef
> of 'name'
> > and the NodeTypeDef of 'pd.getDeclaringNodeType()' and check if the
> second is a
> > supertype of the first.
> >
> > Of course maybe I am not heading towards the right direction
> here...but it is an
> > idea
> >
> > 3) Finally, to find a way arround the previous problem, I did the
> following:
> > Whenever I added an nt:resource property to the new node type; (e.g.
> when I
> > added jcr:data
> > to "my:myresource" propdef array) I also declared my:myresource as the
> declared
> > node type of the property using the following code (in order to avoid
> the
> > previous exception)
> >
> > ws.getNamespaceRegistry().registerNamespace("my",
> >                 "http://www.my.com/my/1.0");
> > QName mResourceName=new QName("http://www.my.com/my/1.0",
> "myresource");
> > ((PropDefImpl)propDefsNew[i]).setDeclaringNodeType(mResourceName);
> >
> > However this approach again failed with a new exception "Not
> implemented"
> >
> > javax.jcr.RepositoryException: not yet implemented
> >
> >         at
> >
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.checkForConflicting
> Content
> > (NodeTypeRegistry.java:1615)
> >
> >         at
> >
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
> > (NodeTypeRegistry.java:1256)
> >
> >
> >
> > Could anybody give me some feedback on the above issues or have any
> ideas how to
> > work arround them to extend a nt:resource node type?
> >
> >
> >
> >
> >
> >
>
>

RE: extend a node type

Posted by Giota Karadimitriou <Gi...@eurodyn.com>.
Dear Peeter,
 
thank you for you response. The reason I was claiming that the
properties are not inherited and tried all those other solutions, was
because when I used the code below to print the property definitions of
the new node type, I was getting only 1 property (my:lang) and that is
why I assumed no properties were inherited. 
However when I ignored these print statements and added jcr:data to a
node of type my:resource it was added ok and Lucene search was able to
search within it.  
 
Thank you for the information you provided and especially for pointing
out the "autocreated" mechanism.
 
Regards
Giota
 
 
QName mResourceName=new QName("http://www.my.com/my/1.0", "myresource");
NodeTypeManager ntMgr=ws.getNodeTypeManager();
NodeTypeRegistry
ntReg=((NodeTypeManagerImpl)ntMgr).getNodeTypeRegistry();
            
           
NodeTypeDef myResource=ntReg.getNodeTypeDef(mResourceName);
PropDef[] propDefs=myResource.getPropertyDefs();
System.out.println("myresource has::"+propDefs.length);
for (int i=0; i<propDefs.length; i++){
     System.out.println("PROP DEF:"+ propDefs[i].getName());
 }
QName superTypes[]=myResource.getSupertypes();
for (int i=0; i<superTypes.length; i++){
                System.out.println("SUPER TYPE:"+
superTypes[i].toString()+" "+superTypes[i].getLocalName());
}
 
 
>myresource has::1
>PROP DEF:{http://www.my.com/my/1.0}lang
> SUPER TYPE:{http://www.jcp.org/jcr/nt/1.0}resource resource
 
-----Original Message-----
From: peeter.piegaze@gmail.com [mailto:peeter.piegaze@gmail.com] On
Behalf Of Peeter Piegaze
Sent: Tuesday, December 13, 2005 5:11 PM
To: jackrabbit-dev@incubator.apache.org
Subject: Re: extend a node type
 
Hi Giota,
 
On 12/13/05, Giota Karadimitriou <Gi...@eurodyn.com>
wrote:
> I am trying to extend the node type "nt:resource" in order to be able
to add
> custom properties to it.
> I started by creating a new node type named my:myresource where 'my'
is a
> registered namespace. I also set the new node type to have a supertype
of
> "nt:resource".
 
This is correct.
 
> However, I ran into the following problems:
>
> 1) Even though the new node type has "nt:resource" as a supertype as I
mentioned
> earlier, it does not automatically inherit any of its properties
> (jcr:data,jcr:encoding,jcr:mimeType and jcr:lastModified). Maybe I am
missing
> sth but if the properties are not inherited, what is in fact inherited
from a
> certain supertype? As far as I can see properties are left out. So is
it
> children or is it sth else?
 
Your new node type *does* inherit the property and child node
definitions of its supertype (in this case nt:resource). For example,
once you create and register your node type my:myresource you can
query its characteristics through the methods of
javax.jcr.nodetype.NodeType, and you will see that it has inherited
the property definitions from nt:resource
 
However, this does not mean that when you create a *new node* using
my:myresource as the node type that these properties will
automatically appear *on the node*. That only happens if the property
or child node in question is defined as "autocreated".
 
In the case of nt:resource, none of the properties are defined as
autocreated so they do not appear automatically.
 
What the node type does is define what properties are *allowed* to be
added to the node --in the case of nt:resource, the prop jcr:encoding
*may* be added-- and what properties *must* be added to the node, in
this case, the other three: jcr:mimeType, jcr:data, and
jcr:lastModified. Notice that these three are defined as "mandatory"
(though not autocreated). This means you (the application) has to add
them  before saving the node (otherwise the save will fail).
 
Currently the best documentation on node types is the JSR 170 spec
itself. There is an extensive chapter covering all these details...and
more.
 
Hope this helps,
Peeter
 
>
> 2)Since the properties were not inherited, I decided to find the
properties of
> nt:resource (PropDefs[]) and add them one by one to the new node type.
I
> therefore created a new PropDef array and I added all "nt:resource"
properties
> to it. I finally added an extra property "my:lang" to it. In the end,
I assigned
> this new PropDef array to the new node type. However, execution failed
with
> Exception
>
> org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException:
>
[{http://www.my.com/my/1.0}myresource#{http://www.jcp.org/jcr/1.0}encodi
ng]
> invalid declaring node type specified
>
>         at
>
org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.validateNodeTypeDef
> (NodeTypeRegistry.java:535)
>
>         at
>
org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
> (NodeTypeRegistry.java:1219)
>
>
>
> This exception occured in validateNodeTypeDef method of
NodeTypeRegistry class
> in the sanity check part of the code where it checks the node type
declaration
> of the property
>
>
> /**
>              * sanity check:
>              * make sure declaring node type matches name of node type
definition
>              */
>             if (!name.equals(pd.getDeclaringNodeType())) {
>                 String msg = "[" + name + "#" + pd.getName()
>                         + "] invalid declaring node type specified";
>                 log.debug(msg);
>                 throw new InvalidNodeTypeDefException(msg);
>             }
>
> and the exception is thrown because 'name' = "my:resource" while
> 'pd.getDeclaringNodeType' = "nt:resource".
> I think this is a bug because at this stage what should be checked is
not
> "equals" but also inheritance. What I mean is that maybe it should be
also
> checked whether 'pd.getDeclaringNodeType()' and 'name' have some other
> connection besides equality, like inheritance for example; because
> "my:myresource" is in fact nt:resource and in such a case, exception
should not
> be thrown
>
> The way to implement what I just said would be to find the NodeTypeDef
of 'name'
> and the NodeTypeDef of 'pd.getDeclaringNodeType()' and check if the
second is a
> supertype of the first.
>
> Of course maybe I am not heading towards the right direction
here...but it is an
> idea
>
> 3) Finally, to find a way arround the previous problem, I did the
following:
> Whenever I added an nt:resource property to the new node type; (e.g.
when I
> added jcr:data
> to "my:myresource" propdef array) I also declared my:myresource as the
declared
> node type of the property using the following code (in order to avoid
the
> previous exception)
>
> ws.getNamespaceRegistry().registerNamespace("my",
>                 "http://www.my.com/my/1.0");
> QName mResourceName=new QName("http://www.my.com/my/1.0",
"myresource");
> ((PropDefImpl)propDefsNew[i]).setDeclaringNodeType(mResourceName);
>
> However this approach again failed with a new exception "Not
implemented"
>
> javax.jcr.RepositoryException: not yet implemented
>
>         at
>
org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.checkForConflicting
Content
> (NodeTypeRegistry.java:1615)
>
>         at
>
org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
> (NodeTypeRegistry.java:1256)
>
>
>
> Could anybody give me some feedback on the above issues or have any
ideas how to
> work arround them to extend a nt:resource node type?
>
>
>
>
>
>

Re: extend a node type

Posted by Peeter Piegaze <pe...@day.com>.
Hi Giota,

On 12/13/05, Giota Karadimitriou <Gi...@eurodyn.com> wrote:
> I am trying to extend the node type "nt:resource" in order to be able to add
> custom properties to it.
> I started by creating a new node type named my:myresource where 'my' is a
> registered namespace. I also set the new node type to have a supertype of
> "nt:resource".

This is correct.

> However, I ran into the following problems:
>
> 1) Even though the new node type has "nt:resource" as a supertype as I mentioned
> earlier, it does not automatically inherit any of its properties
> (jcr:data,jcr:encoding,jcr:mimeType and jcr:lastModified). Maybe I am missing
> sth but if the properties are not inherited, what is in fact inherited from a
> certain supertype? As far as I can see properties are left out. So is it
> children or is it sth else?

Your new node type *does* inherit the property and child node
definitions of its supertype (in this case nt:resource). For example,
once you create and register your node type my:myresource you can
query its characteristics through the methods of
javax.jcr.nodetype.NodeType, and you will see that it has inherited
the property definitions from nt:resource

However, this does not mean that when you create a *new node* using
my:myresource as the node type that these properties will
automatically appear *on the node*. That only happens if the property
or child node in question is defined as "autocreated".

In the case of nt:resource, none of the properties are defined as
autocreated so they do not appear automatically.

What the node type does is define what properties are *allowed* to be
added to the node --in the case of nt:resource, the prop jcr:encoding
*may* be added-- and what properties *must* be added to the node, in
this case, the other three: jcr:mimeType, jcr:data, and
jcr:lastModified. Notice that these three are defined as "mandatory"
(though not autocreated). This means you (the application) has to add
them  before saving the node (otherwise the save will fail).

Currently the best documentation on node types is the JSR 170 spec
itself. There is an extensive chapter covering all these details...and
more.

Hope this helps,
Peeter

>
> 2)Since the properties were not inherited, I decided to find the properties of
> nt:resource (PropDefs[]) and add them one by one to the new node type. I
> therefore created a new PropDef array and I added all "nt:resource" properties
> to it. I finally added an extra property "my:lang" to it. In the end, I assigned
> this new PropDef array to the new node type. However, execution failed with
> Exception
>
> org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException:
> [{http://www.my.com/my/1.0}myresource#{http://www.jcp.org/jcr/1.0}encoding]
> invalid declaring node type specified
>
>         at
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.validateNodeTypeDef
> (NodeTypeRegistry.java:535)
>
>         at
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
> (NodeTypeRegistry.java:1219)
>
>
>
> This exception occured in validateNodeTypeDef method of NodeTypeRegistry class
> in the sanity check part of the code where it checks the node type declaration
> of the property
>
>
> /**
>              * sanity check:
>              * make sure declaring node type matches name of node type definition
>              */
>             if (!name.equals(pd.getDeclaringNodeType())) {
>                 String msg = "[" + name + "#" + pd.getName()
>                         + "] invalid declaring node type specified";
>                 log.debug(msg);
>                 throw new InvalidNodeTypeDefException(msg);
>             }
>
> and the exception is thrown because 'name' = "my:resource" while
> 'pd.getDeclaringNodeType' = "nt:resource".
> I think this is a bug because at this stage what should be checked is not
> "equals" but also inheritance. What I mean is that maybe it should be also
> checked whether 'pd.getDeclaringNodeType()' and 'name' have some other
> connection besides equality, like inheritance for example; because
> "my:myresource" is in fact nt:resource and in such a case, exception should not
> be thrown
>
> The way to implement what I just said would be to find the NodeTypeDef of 'name'
> and the NodeTypeDef of 'pd.getDeclaringNodeType()' and check if the second is a
> supertype of the first.
>
> Of course maybe I am not heading towards the right direction here...but it is an
> idea
>
> 3) Finally, to find a way arround the previous problem, I did the following:
> Whenever I added an nt:resource property to the new node type; (e.g. when I
> added jcr:data
> to "my:myresource" propdef array) I also declared my:myresource as the declared
> node type of the property using the following code (in order to avoid the
> previous exception)
>
> ws.getNamespaceRegistry().registerNamespace("my",
>                 "http://www.my.com/my/1.0");
> QName mResourceName=new QName("http://www.my.com/my/1.0", "myresource");
> ((PropDefImpl)propDefsNew[i]).setDeclaringNodeType(mResourceName);
>
> However this approach again failed with a new exception "Not implemented"
>
> javax.jcr.RepositoryException: not yet implemented
>
>         at
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.checkForConflictingContent
> (NodeTypeRegistry.java:1615)
>
>         at
> org.apache.jackrabbit.core.nodetype.NodeTypeRegistry.reregisterNodeType
> (NodeTypeRegistry.java:1256)
>
>
>
> Could anybody give me some feedback on the above issues or have any ideas how to
> work arround them to extend a nt:resource node type?
>
>
>
>
>
>