You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jackrabbit.apache.org by Nandana Mihindukulasooriya <na...@gmail.com> on 2007/03/23 09:33:19 UTC

How to start thinking in JCR

         I'm planning to do a jackrabbit-jcr-demo in the Google Summer of
Code and one of the important deliverable of it would be the documentation.
My plain is to raise questions and have discussions through out the project
and grab the expertise of all the well experienced jackrabbit programmers in
the mailing list and put it in to a documentation in a structured way so
that a new comer won't have to go through all the mail archives to find the
information.

        So I thought of starting from the very beginning. Say if we are
using a relational database, we can model our data in business and their
relationships in an ER or an EER diagram then convert in to relations and
normalize them.  When we are using JCR what is the best approach for content
modeling? How should one start content modeling? I should thank Xin and
other developers for his discussion on content modeling, it is really
beneficial to me too and I am learning lot of basic things from that
discussion. I am following that discussion very carefully to learn things.
But here I raised the question again to get a more general answer at a more
basic level.

        I would really thankful if all the expert jackrabbit users can
contribute so that I will be able to document all the important points you
have gained through experience and it will be very useful to a new
jackrabbit programmer.



Thank you in advance

Nandana

Re: How to start thinking in JCR

Posted by alartin <al...@gmail.com>.
Hi Nunny,


Nunny wrote:
> 
> Hi,
> 
> On 3/24/07, Brian Thompson <el...@gmail.com> wrote:
>>
>> Comments interleaved below:
>>
>> Oh, one other thing:  In your model, do you ever expect the same image
>> to be attached to multiple BlogEntries?
> 
> 
> Nope,  Same image will not be attached to multiple Blog Entires. But if it
> is the case, as I understood I should use property of reference type in
> the
> blog entry which references to a image attachment. Is that the way to
> handle
> it ?
> 
> 
>> I went through the Node Type sections of the Jackrabbit site and also
>> 6.7Node Types of the JSR 170 specification. As I understood,
> 
> A node type defines the  Child nodes and properties it may ( or must )
> have.
> 
> Primary node type must be subtype of either primary or a mixin type and
> mixin type may have a super type and it is not a must.
> 
> I have few questions and some of them may be obsolete. But I listed them
> down as it is always better have a discussion and get things clarified.
> 
> 1.) In naming node types and properties, do we follow the naming
> conventions
> used in Java ?
> Eg. myFristType
> 
> IMO, Yes. It's better to follow it.
> 
> 2.) What is purpose mixin node type ?  Purpose of primary node is to
> define
> the structure of the node as I understood. What is the advantage of adding
> some properties or child nodes  via mixin types to a node ?
> 
> I think primary and mixin in JCR are much like class and interface in
> Java.
> Node must have ONE primary type: Class can only extend one class
> Node can have many mixin types: Class can implements many interfaces
> In one word, interface provides a function ability, same as mixin and
> think
> mixin as the interface.  You should only define functional properties and
> child nodes to mixin
> ,for example: uuid to mix:referenceable. uuid is a must property to
> achieve that reference ability/funciton
> ,so define uuid in the mixin, while cotent (for example) property is
> irrelated to that, keep it out of the mixin.
> I think you should treat them as you treat class and interface in Java.
> Think about when should extend a class
> and when should implement an interface and when use interface instead of
> extending a class.
> 
> 3.) What is the purpose of primary item of a node type?
> IMO, just for the convenient mehtod, it privodes a way to get the primary
> item without knowing its name.
> 
> 4.) In a property definition, in Required Type, what does NAME, PATH types
> mean ?
> 
> 5.) Is int supported as a property type ? It is not listed under  the
> property_type in the grammer.
> Use long instead of int
> 
> 6.) How to we constraint a property of a node to be unique ( like a
> primary
> key in RDBMS ) ?
> No way. Make your unique entity as a referenceable node A, then make a
> node B  a property C with reference type, C stores the A's uuid. So you
> can get it:   Node B --
>                                                                          
> |__C    ----->   Node A
> Thus node B only points to one unique Node A
> 
> 
> 
> As you proposed, if we change the hierarchy like this,
> 
>                 - Users
>                          -  Year
>                                   - Month
> 
>       - Date
> 
>              -  Blog Entry
> 
>                        -  Comment
> 
>                        -  Rate
> 
>                        -  Image Attachment
> 
> 
> 
> In CND notation,
> 
> <blog = 'http://jackrabbit.apache.org/jackrabbit-jcr-demo/1.0'>
> 
> <mix = 'http://www.jcp.org/jcr/mix/1.0'>
> 
> [blog:user] > mix:referenceable
> 
> -          blog:userID   (long) mandatory
> 
> -          blog:nickName  (string) mandatory
> 
> -          blog:email  (string) mandatory
> 
> -          blog:password (string) mandatory
> 
> + blog:year  [blog:year] multiple
> 
> 
> [blog:year]
> 
> -          blog:year  (long) mandatory
> 
> +   blog:month  [blog:month] multiple
> 
> 
> [blog:date]
> 
> -          blog:date (date)
> 
> +  blog:blogEntry [blog:blogEntry] multiple
> 
> 
> [blog:blogEntry]
> 
> -          blog:blogEntryID (long) mandatory
> 
> -          blog:content (string) mandatory
> 
> -          blog:image (binay) multiple
> 
> -          blog:rate (long)
> 
> -          blog:dateCreated (date) mandatory
> 
> +    blog:comment [blog:comment] multiple
> 
> 
> 
> [blog:comment]
> 
> -          blog:commentID (long) mandatory
> 
> -          commenterID (reference) mandatory  < blog:user
> 
> -          blog:content (string) mandatory
> 
> -          blog:dateCreated (date) mandatory
> 
> 

-- 
View this message in context: http://www.nabble.com/How-to-start-thinking-in-JCR-tf3452522.html#a9687041
Sent from the Jackrabbit - Users mailing list archive at Nabble.com.


Re: How to start thinking in JCR

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
HI,


> The URLs are "clean" and map one-to-one to nodes in the repository.
> And the best part is that you don't need to put any custom "a URL like
> this should be processed like this" rules in your application, as you
> can just use the primary node type of the target node to select the
> appropriate view component for displaying the node contents.


Thanks, now I understand the advantage of having a simplified title as the
node name
of blogEntry node type as we discussed in an earlier mail. so the
requirements of the simplification algorithm would be,

1. It should remove white spaces and other special characters which doesn't
fit in to urls
2. It should make the nodename unique with respect to it's siblings so the
one-to-one mapped urls are unique too.
(Blog entries can have same title and it's algorithms responsibility to make
them unique )
3. It should preserve the readability of the title as much as possible.


You might also want to consider custom created/published/updated
> timestamp properties, as the standard jcr:created is somewhat
> inflexible (once created it can't be modified).


Does the property type DATE behaves as the same way most of the
RDBMS behave. If we make it autocreated and don't give it a default
value, does it take the current timestamp.


Add "> nt:hierarchyNode" to allow comments to be stored as normal
> child elements of the nt:folder blog entry node.



That will also give us the jcr:created property which will be useful in
date-based listing of comments.


-----------------------------------------------     Node Structure
--------------------------------------

/blogRoot [nt:folder]
/blogRoot/user [blog:user]
/blogRoot/user/<yyyy> [nt:folder]
/blogRoot/user/<yyyy>/<mm> [nt:folder]
/blogRoot/user/<yyyy>/<mm>/blogEntry [blog:blogEntry]
/blogRoot/user/<yyyy>/<mm>/blogEntry/comment [blog:Comment]
/blogRoot/user/avatar [nt:file]
/<libray> [nt:folder]


---------------------------------   CND Notation for custom types
------------------------------

<blog = 'http://jackrabbit.apache.org/jackrabbit-jcr-demo/1.0'>
<mix = 'http://www.jcp.org/jcr/mix/1.0'>
<nt = 'http://www.jcp.org/jcr/nt/1.0'>

[blog:user] >  nt:folder, mix:referenceable
- blog:nickname  (string) mandatory
- blog:email  (string) mandatory
- blog:password (string) mandatory


[blog:blogEntry] > nt:folder, mix:referenceable
- blog:title (string) mandarory primary
- blog:content (string) mandatory
- blog:rate (long)
- blog:created (date) autocreated
- blog:published (date)
- blog:updated (date)


[blog:comment] > nt:hierarchyNode
- blog:content (string) mandatory primary
- blog:commenter (reference ) mandatory  < blog:user


BR,
Nandana

Re: How to start thinking in JCR

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On 4/9/07, Nandana Mihindukulasooriya <na...@gmail.com> wrote:
> > Also, there's a chance to drop the explicit blog:library and
> > blog:blogSpace child node definitions if you make blog:user extend
> > nt:folder. Then you could simply have "library" and "blog" subfolders
> > within the user node, or even avoid those subfolders entirely and rely
> > on node types to detect which child nodes are blog entries and which
> > are other resources.
>
> Does it mean a structure like,
>
>  /blogRoot/user/ <yyyy>/<mm> /blogEntry [blog:blogEntry]
>  /blogRoot/user/<avatar.gif> [nt:file]
>
>  Or a structure like,
>
>  /blogRoot/user/blogEntry [blog:blogEntry]
>  /blogRoot/user/<avatar.gif> [nt:file]
>
> In the latter one, are we using the jcr:created property of  nt:hierarchyNode
> if we want to list the blog entries according to date or month.

I would use the former structure (with yyyy/mm) as discussed in
previous messages. In any case, for date-based listings it makes sense
to use a subtree query like
"/jcr:root/blogRoot/user//element(*,blog:blogEntry) order by
@jcr:created" to avoid hardcoding the folder structure in your
application. The yyyy/mm structure is more designed to avoid too many
child nodes in one place and to make it easier to administer the
content, not that much as a way to organize normal read access.

> > It's a tradeoff between flexibility and more
> > completely specifying the content structure.
> >
> > I would actually suggest we take this opportunity for extra
> > flexibility since it gives some very nice late binding benefits when
> > we later start defining the URL mapping for the application.
> >
> By flexibility, does it mean the flexibility we have to change the structure
> as we want in the future ? How does this help to get the late binding
> benefits?

The benefit is that without the explicit blog:blogSpace and
blog:library subfolders, we can do a clean and direct URL to path
mapping without any hardcoded information about the application
structure. Consider the URL space for such a blog application:

    .../jukka/ -> /blogRoot/jukka [blog:user]
    .../jukka/2007/04/hello/ -> /blogRoot/jukka/2007/04/hello [blog:blogEntry]
    .../jukka/2007/04/hello/world.pdf ->
/blogRoot/jukka/2007/04/hello/world.pdf [nt:file]
    .../jukka/avatar.png -> /blogRoot/jukka/avatar.png [nt:file]

The URLs are "clean" and map one-to-one to nodes in the repository.
And the best part is that you don't need to put any custom "a URL like
this should be processed like this" rules in your application, as you
can just use the primary node type of the target node to select the
appropriate view component for displaying the node contents.

> [blog:user] >  nt:hierarchyNode, mix:referenceable

Use nt:folder instead of nt:hierarchyNode as the parent type to allow
the custom substructure described above.

> [blog:blogEntry] > nt:hierarchyNode, mix:referenceable
> - blog:title (string) mandarory primary
> - blog:content (string) mandatory
> - blog:rate (long)
> + blog:attachments (nt:folder) =nt:folder mandatory autocreated

Here we could do the same thing, allow attachments directly below the
blog entries without the intermediate blog:attachments folder. Just
change the supertype from nt:hierarchyNode to nt:folder. This also
allows us to place the comments as nt:hierarchyNode subnodes within
the same subtree.

You might also want to consider custom created/published/updated
timestamp properties, as the standard jcr:created is somewhat
inflexible (once created it can't be modified).

>  [blog:comment]
> - blog:content (string) mandatory primary
> - blog:commenter (reference ) mandatory  < blog:user

Add "> nt:hierarchyNode" to allow comments to be stored as normal
child elements of the nt:folder blog entry node.

BR,

Jukka Zitting

Re: How to start thinking in JCR

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
Hi,


> Also, there's a chance to drop the explicit blog:library and
> blog:blogSpace child node definitions if you make blog:user extend
> nt:folder. Then you could simply have "library" and "blog" subfolders
> within the user node, or even avoid those subfolders entirely and rely
> on node types to detect which child nodes are blog entries and which
> are other resources.


Does it mean a structure like,

 /blogRoot/user/ <yyyy>/<mm> /blogEntry [blog:blogEntry]
 /blogRoot/user/<avatar.gif> [nt:file]

 Or a structure like,

 /blogRoot/user/blogEntry [blog:blogEntry]
 /blogRoot/user/<avatar.gif> [nt:file]

 In the latter one, are we using the jcr:created property of  nt:hierarchyNode
if we want to list the blog entries according to date or month.



> It's a tradeoff between flexibility and more
> completely specifying the content structure.
>
> I would actually suggest we take this opportunity for extra
> flexibility since it gives some very nice late binding benefits when
> we later start defining the URL mapping for the application.
>
By flexibility, does it mean the flexibility we have to change the structure
as we want in the future ? How does this help to get the late binding
benefits ?



----------------------------------   Node Structure
---------------------------------

 /blogRoot [nt:folder]
/blogRoot/user [blog:user]
/blogRoot/user/ blogEntry [blog:blogEntry]
/blogRoot/user/ blogEntry /comment [blog:Comment]
/blogRoot/user/avatar [nt:file]
/<libray> [nt:folder]


------------------------------   CND Notation for custom types
------------------------

<blog = 'http://jackrabbit.apache.org/jackrabbit-jcr-demo/1.0'>
<mix = 'http://www.jcp.org/jcr/mix/1.0'>
<nt = 'http://www.jcp.org/jcr/nt/1.0'>

[blog:user] >  nt:hierarchyNode, mix:referenceable
- blog:nickname  (string) mandatory
- blog:email  (string) mandatory
- blog:password (string) mandatory

[blog:blogEntry] > nt:hierarchyNode, mix:referenceable
- blog:title (string) mandarory primary
- blog:content (string) mandatory
- blog:rate (long)
+ blog:attachments (nt:folder) =nt:folder mandatory autocreated

 [blog:comment]
- blog:content (string) mandatory primary
- blog:commenter (reference ) mandatory  < blog:user

BR,

Nandana

Re: How to start thinking in JCR

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
Hi,
   Thank you very much Brian and Jukka for the comments. This is the code I
used earlier (without error handling),

Workspace workSpace = session.getWorkspace();
String CNDFile = "…";
FileReader fileReader = *new* FileReader(cndFileName);
CompactNodeTypeDefReader cndReader =
*new*CompactNodeTypeDefReader(fileReader, cndFileName);
List ntdList = cndReader.getNodeTypeDefs();
NodeTypeManagerImpl  ntmgr = (NodeTypeManagerImpl)ws.getNodeTypeManager()
NodeTypeRegistry ntreg = ntmgr.getNodeTypeRegistry();
NodeTypeDef ntd = (NodeTypeDef)ntdList.next()
ntreg.registerNodeType(ntd);

But now I'm using Jackrabbit 1.2.3 , with JSR - 349, I can simply use

file = *new* File("CNDFile");
FileInputStream inputStream = *new* FileInputStream(file);
Workspace workSpace = session.getWorkspace();
NodeTypeManagerImpl ntTypeMgr = (NodeTypeManagerImpl) workSpace
.getNodeTypeManager();
ntTypeMgr.registerNodeTypes(inputStream,JackrabbitNodeTypeManager.*
TEXT_X_JCR_CND*,*false*);


But when I tried to use it with the registerExisting flag true, it gave me
an exception at line,

*return* (NodeType[]) nodeTypes.toArray(*new* NodeTypeDef[nodeTypes.size
()]);

Exception in thread "main" *java.lang.ArrayStoreException*
    at java.lang.System.arraycopy(*Native Method*)
    at java.util.ArrayList.toArray(*ArrayList.java:304*)
    at
org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl.registerNodeTypes(*
NodeTypeManagerImpl.java:295*)
    at nandana.jackrabbit.example1.NodeStructuteNew.main(*
NodeStructuteNew.java:34*)


I was able to fix type conflict by changing that line to

*return* (NodeType[]) nodeTypes.toArray(*new* NodeType[nodeTypes.size()])

I will go through content structure again and do the modifications. Thanks.

BR,
Nandana

Re: How to start thinking in JCR

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On 4/3/07, Nandana Mihindukulasooriya <na...@gmail.com> wrote:
> Does all properties have to have a namespace prefix ? When I tried
> to register the node types using the CompactNodeTypeDefReader it
> gave an error caused by "UnknownPrefixException".

You can have properties in the default namespace with no namespace
prefix. Since Jackrabbit 1.0.1 there hasn't been a need to include the
default namespace prefixes in the CND file (see JCR-383), so I don't
think that's an issue with your CND file.

Check that the "blog" prefix definition is included in the CND file
you feed to Jackrabbit, and that there's no typo in the property
definition. I'm not sure if the CND you included in your message is
the one you're using since you had replaced parts with "...".

> Like Node class's hasNode() method is there convinient methods to check
> whether a namespace prefix is already registered ?

Not really. You can use the Session.getNamespacePrefix() method and
catch the exception if needed. However, since the 1.1 release
Jackrabbit has automatically registered the namespaces included in the
CND files given for registration, so you shouldn't need to worry about
that. See JCR-349 for the details.

> and to check whether a Node Type is already registed ? I didn't find such
> methods in NodeTypeManager or NamespaceRegistry Interfaces of JCR.
> I used the NodeTypeManagerImpl which inplements the
> JackrabbitNodeTypeManager Interface.

In the 1.1 release we added the
JackrabbitNodeTypeManager.hasNodeType() utility method designed for
just this purpose. See JCR-521 for the details.

> But in the mailing list
> // only register the type if it does not yet exist
>     if (!manager.hasNodeType("myfile"))
> is used to check this. Is that method not available in Jackrabbit 1.0 ?

No, only in Jackrabbit 1.1 and higher. I suggest that you use the
latest Jackrabbit release in your work.

> To create a the repository I used the TransientRepository class which
> created me a default repository configuration file. But if I am using JNDI binding
> do I have to create a repository.xml by my self ? Is there a way to specify
> to create a default configuration ?

It depends on how you do the JNDI binding. For example if you follow
the deployment model 2 instructions for Tomcat
(http://jackrabbit.apache.org/doc/deploy/howto-model2.html), you need
to specify the path to the repository.xml configuration file. You can
use the default one created by TransientRepository.

> Where can I find contrib/compact-nt tools ?

The code in the compact-nt contrib project was moved to
org.apache.jackrabbit.core.nodetype.compact within the jackrabbit-core
component. Nowadays you shouldn't need to access the functionality
directly, instead use the JackrabbitNodeTypeManager extension
interface.

> [blog:user] > mix:referenceable
> - blog:nickname  (string) mandatory
> - blog:email  (string) mandatory
> - blog:password (string) mandatory
> + blog:library (nt:folder) =nt:folder mandatory autocreated
> + blog:blogSpace (nt:folder) =nt:folder mandatory autocreated

You'll want to make blog:user extend nt:hierarchyNode to make it
possible to create blog:user nodes within nt:folder.

Also, there's a chance to drop the explicit blog:library and
blog:blogSpace child node definitions if you make blog:user extend
nt:folder. Then you could simply have "library" and "blog" subfolders
within the user node, or even avoid those subfolders entirely and rely
on node types to detect which child nodes are blog entries and which
are other resources. It's a tradeoff between flexibility and more
completely specifying the content structure.

I would actually suggest we take this opportunity for extra
flexibility since it gives some very nice late binding benefits when
we later start defining the URL mapping for the application.

BR,

Jukka Zitting

Re: How to start thinking in JCR

Posted by Brian Thompson <el...@gmail.com>.
In your CND-file, you need to declare all the namespaces you'll use, even
the ones that come with Jackrabbit:

==============================

/* orig.namespaces */
<mix = 'http://www.jcp.org/jcr/mix/1.0'>
<nt = 'http://www.jcp.org/jcr/nt/1.0'>

/* my stuff */
<my = 'http://www.example.com/jcr-ns/my'>

<page = 'http://www.example.com/jcr-ns/page'>

[my:page] > nt:unstructured, mix:referenceable
        orderable
        - my:active (boolean) = 'true' mandatory autocreated

=======================

etc...


On 4/2/07, Nandana Mihindukulasooriya <na...@gmail.com> wrote:
>
> Hi,
>      I changed the Node structure as following according to the discussion
> and tried to register them in the repository. Here are some of the
> problems
> I came across.
>
> Grammer for CND notation defines a property of a Node type as
>
> property_def ::= "-" property_name [property_type_decl]
>                  [default_values] [attributes]
>                  [value_constraints]
> property_name ::= string
>
> Does all properties have to have a namespace prefix ? When I tried
> to register the node types using the CompactNodeTypeDefReader it
> gave an error caused by "UnknownPrefixException".
>
> It also said that if I define the autocreated attribute for a childnode
> I should define the default type for them which is of cource reasonable.
>
> Like Node class's hasNode() method is there convinient methods to check
> whether a namespace prefix is already registered ? and to check whether
> a Node Type is already registed ? I didn't find such methods in
> NodeTypeManager or NamespaceRegistry Interfaces of JCR. I used the
> NodeTypeManagerImpl which inplements the JackrabbitNodeTypeManager
> Interface.
>
> But in the mailing list
> // only register the type if it does not yet exist
>     if (!manager.hasNodeType("myfile"))
> is used to check this. Is that method not available in Jackrabbit 1.0 ?
>
> To create a the repository I used the TransientRepository class which
> created
> me a default repository configuration file. But if I am using JNDI binding
> do I have to create a repository.xml by my self ? Is there a way to
> specify
> to
> create a default configuration ?
>
> Where can I find contrib/compact-nt tools ?
>
> I really appreciate your comments. Thank you in advance.
>
> BR,
> Nandana
>
>
> ----------------------------------------------------- Node Structure
> -------------------------------------------------------
>
> /blogRoot [nt:folder]
> /blogRoot/user [blog:user]
> /blogRoot/user/blogSpace [nt:folder]
> /blogRoot/user/blogSpace/<yyyy> [nt:folder]
> /blogRoot/user/blogSpace/<yyyy>/<mm> [nt:folder]
> /blogRoot/user/blogSpace/<yyyy>/<mm>/blogEntry [blog:blogEntry]
> /blogRoot/user/blogSpace/<yyyy>/<mm>/blogEntry/comment [blog:Comment]
> /blogRoot/user/library [nt:folder]
> /blogRoot/user/libray/avatar [nt:file]
> /<libray> [nt:folder]
>
> -------------------------------------------   CND Notation for custom
> types   -------------------------------------
>
>
> <blog = 'http://jackrabbit.apache.org/jackrabbit-jcr-demo/1.0'>
> <nt =  ... >
> <jcr =  ... >
>
>
> [blog:user] > mix:referenceable
> - blog:nickname  (string) mandatory
> - blog:email  (string) mandatory
> - blog:password (string) mandatory
> + blog:library (nt:folder) =nt:folder mandatory autocreated
> + blog:blogSpace (nt:folder) =nt:folder mandatory autocreated
>
>
> [blog:blogEntry] > nt:hierarchyNode, mix:referenceable
> - blog:title (string) mandarory primary
> - blog:content (string) mandatory
> - blog:rate (long)
> + blog:attachments (nt:folder) =nt:folder mandatory autocreated
>
> [blog:comment]
> - blog:content (string) mandatory primary
> - blog:commenter (reference ) mandatory  < blog:user
>
> -----------------------------------------------------------   Stack trace
> -----------------------------------------------------
>
> org.apache.jackrabbit.core.nodetype.compact.ParseException: Error while
> parsing 'nickname'
>     at org.apache.jackrabbit.core.nodetype.compact.Lexer.fail(Lexer.java
> :146)
>     at
>
> org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.toQName
> (CompactNodeTypeDefReader.java:635)
>     at
>
> org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.doPropertyDefinition
> (CompactNodeTypeDefReader.java:373)
>     at
>
> org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.doItemDefs
> (CompactNodeTypeDefReader.java:331)
>     at
> org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.parse
> (
> CompactNodeTypeDefReader.java:208)
>     at
> org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader
> .<init>(CompactNodeTypeDefReader.java:165)
>     at
> org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader
> .<init>(CompactNodeTypeDefReader.java:150)
>     at nandana.jackrabbit.example1.NodeStructure.RegisterCustomNodeTypes(
> NodeStructure.java:94)
>     at nandana.jackrabbit.example1.NodeStructure.main(NodeStructure.java
> :58)
> Caused by: org.apache.jackrabbit.name.UnknownPrefixException:
>     at org.apache.jackrabbit.name.QName.fromJCRName(QName.java:596)
>     at
>
> org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.toQName
> (CompactNodeTypeDefReader.java:630)
>     ... 7 more
> Exception in thread "main" java.lang.NullPointerException
>     at nandana.jackrabbit.example1.NodeStructure.RegisterCustomNodeTypes(
> NodeStructure.java:101)
>     at nandana.jackrabbit.example1.NodeStructure.main(NodeStructure.java
> :58)
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> On 3/28/07, Jukka Zitting <ju...@gmail.com> wrote:
> >
> > Hi,
> >
> > On 3/29/07, Nandana Mihindukulasooriya <na...@gmail.com> wrote:
> > > I should thank Brian, Xin and Jukka a lot for their valuable feedbacks
> > > and I was able to understand lot of things when I went through the
> > > JSR-170 again after reading the feedbacks.
> >
> > Excellent, thanks again for your efforts. Comments below...
> >
> > > Now we will create users using their unique user IDs like
> > >
> > > Node root = session.getRootNode();
> > > Node user = root.addNode("uniqueUserID","blog:user");
> > >
> > > To avoid uniqueUserID conflit with other root's child nodes ( which
> are
> > not
> > > user nodes), can we use a namespace prefix as "id:uniqueID" with <id =
> > > http://... >.
> >
> > Namespaces are a good way to avoid naming conflicts, but in this case
> > an even better way would be to create your own "application root node"
> > like /blog:root like the one you propose below. Such a root node
> > nicely separates the blog content from any other application you may
> > want to store in the same workspace. It also makes it easy to limit
> > searches to just that subtree instead of including for example the
> > whole /jcr:system tree.
> >
> > Also, I would encourage you to use a username or even the real name of
> > the user as the node name instead of a numeric or some other abstract
> > identifier.
> >
> > Thus the code would be:
> >
> >     Node root = session.getRootNode().getNode("blog:root");
> >     Node user = root.addNode(username,"blog:user");
> >
> > > can we add something like this to root node to avoid non-unique
> userIDs
> > ?
> > >
> > >     ChildNodeDefinition
> > >     Name *
> > >     RequiredPrimaryTypes UNDEFINED
> > >     ...
> > >     SameNameSiblings false
> >
> > The root node definition in Jackrabbit is essentially equivalent to
> > nt:unstructured, so you can already add whatever child nodes you want
> > to it without modifying the type definition.
> >
> > > If we can, how can we define it ? and is ItemExistsException throwed
> > > immediately or on save in jackrabbit implementation of jcr ?
> > > If we can't is there any other way to prevent it ?
> >
> > Node types can be registered using the CND or XML node type definition
> > formats and the JackrabbitNodeTypeManager extension interface found in
> > the jackrabbit-api component.
> >
> > Generally you shouldn't rely on an JCR implementation to perform
> > consistency checks before the save() call. There are even many full
> > consistency checks that can logically not be performed before the
> > save() call.
> >
> > > or can I make a one root note child like this and define it not to
> have
> > > sameNameSiblings.
> > >
> > > [blog:blog]
> > >     - * [blog:user]
> > >     - library [nt:folder] mandatory autocreated
> >
> > Such an approach would be my preferred alternative. You can't easily
> > constraint the repository root node not to have children with same
> > names, but you can quite easily enforce that in your application.
> >
> > As to the blog:blog node type, again I would prefer the standard
> > nt:folder type. I'd also place the image library under a separate
> > "content root" since it could very well be used by other applications
> > as well. The content tree would look something like this:
> >
> >     /blog:blog [nt:folder]
> >     /blog:blog/...
> >     /blog:library [nt:folder]
> >     /blog:library/...
> >
> > You can initialize your application like this (assuming you've already
> > set up the namespaces):
> >
> >     Session session = ...;
> >     Node root = session.getRootNode();
> >     if (!root.hasNode("blog:blog")) {
> >         root.addNode("blog:blog", "nt:folder");
> >     }
> >     if (!root.hasNode("blog:library")) {
> >         root.addNode("blog:library", "nt:folder");
> >     }
> >     session.save();
> >
> > > As blogspace is of type nt:folder which has a child node definition,
> > >
> > >     ChildNodeDefinition
> > >     Name *
> > >     RequiredPrimaryType[nt:hierarchyNode]
> > >
> > > it can in turn have children of type nt:folder as nt:folder is
> > a  subtype of
> > > nt:hierarchyNode. So both <yyyy> and <mm> would be nodes of type
> > nt:folder.
> >
> > Exactly.
> >
> > > So we can use,
> > >
> > > Node blogSpace = user.getNode("blogSpace");
> > > Node year = blogspace.addNode("2007","nt:folder");
> > > Node month = year.addNode("03","nt:folder");
> > >
> > > Is there a way to create a node with intermediate created
> automatically
> > ?
> > > If there is a way, how can we declare the types of intermediate nodes
> ?
> > > Javadoc says it throws a PathNotFoundException if we try to create a
> > > node without creating intermediate nodes.
> >
> > There's no such way, you need to handle that in your application.
> >
> >     Node blogSpace = ...;
> >     if (!blogSpace.hasNode("year")) {
> >         blogSpace.addNode("year", "nt:folder");
> >         blogSpace.save();
> >     }
> >     Node year = blogSpace.getNode("year");
> >     if (!year.hasNode("month")) {
> >         year.addNode("month", "nt:folder");
> >         year.save();
> >     }
> >     Node month = year.getNode("month");
> >
> > Note that the above code has a slight chance of race conditions if two
> > sessions attempt to create the same intermediate nodes at the same
> > time. You can either proactively prevent it by making the blogSpace
> > node lockable and using JCR locks, or you can catch the concurrent
> > modification exception and recover by retrying the operation. Since
> > the chance of collisions is so small, I would go with the latter
> > option.
> >
> > > So we have to come with a way to name the blog entries. Title may not
> be
> > a
> > > good candidate because they may white spacses and '.', '/', ':', '[',
> > ']', '*',
> > > ''', '"' charactors. Would a simple sequential numbering work ? Is
> there
> > a better
> > > way to handle this ?
> >
> > Generally a somewhat meaningful name is preferred over a sequence
> > number. It makes administration much easier and also gives a nice
> > URL-to-path mapping for web applications. I would go for a solution
> > that either allows the user to specify the node name or uses a
> > "simplifies" title as the node name. Many existing blog applications
> > (for example WordPress) already use a "simplification" algorithm that
> > turns title strings into valid URL path components. A similar solution
> > would be perfect here as well.
> >
> > You would still store the full title as a normal string property to
> > avoid losing data.
> >
> > > Node blogEntry = month.addNode("01","blog:blogEntry");
> > > blogEntry.setProperty("content","my first blog entry");
> > >
> > > As blogEntry is a subtype of nt:hierarchyNode, I would be able to use
> > > jcr:created property to get the created date of the blog.
> >
> > Exactly.
> >
> > > To add an image attachment,
> > >
> > > Node attachments = blogEntry.getNode("attachments");
> > > Node linkedFile = attachments.addNode("attachment01","nt:linkedFile");
> > > linkedFile.setProperty("jcr:content",root.getNode("library/xxx/yyy"));
> > >
> > > jcr:content property of the  nt:linkedFile  type  is of type
> reference.
> >
> > Perfect. Note that the jcr:content reference of an nt:linkedFile node
> > should probably point to the jcr:content resource node of another file
> > instead of the file node itself.
> >
> > > To add a Comment
> > >
> > > Node comment = blogEntry.addNode("01","blog:comment");
> > > comment.setProperty("content","my first comment");
> > > comment.setProperty("commenter", root.getNode("commenterID"));
> >
> > Exactly.
> >
> > > To add a avator to a user,
> > >
> > > Node library = root.getNode("library");
> > > Node manAvatar = library.addNode("manAvator","blog:avatar");
> > > Node content = manAvatar.getNode("jcr:content");
> > > content.setProperty("image",imageInputStream);
> > >
> > > user.setProperty("avatar",manAvator);
> >
> > I think you'd be better of again using the standard nt:hierarchyNode
> > model here instead of custom types. I would define a "personal
> > library" folder for each user and place the avatar image there as
> > either a local nt:file or as a nt:linkedFile that refers to some image
> > in the global image library. A reserved name would be used for the
> > avatar image, but other files could also be stored in this personal
> > library folder. Using the standard node types allows you for example
> > to use the existing WebDAV servlet classes from jackrabbit-jcr-server
> > to serve the content in a web application. As an extra bonus you'd
> > even get PUT support for free for remote clients to update the
> > content!
> >
> >     [blog:user]
> >     ....
> >     + library (nt:folder) mandatory autocreated
> >
> > Adding a custom avatar would be:
> >
> >     Node user = ...;
> >     Node library = user.getNode("library");
> >     Node avatar = library.addNode("avatar", "nt:file");
> >     avatar.addNode("jcr:content", "nt:resource");
> >     avatar.setProperty("jcr:content/jcr:mimeType", "image/gif");
> >     avatar.setProperty("jcr:content/jcr:lastModified",
> > Calendar.getInstance());
> >     avatar.setProperty("jcr:content/jcr:data", ...);
> >     library.save();
> >
> > Adding a standard avatar from the global image library would be:
> >
> >     Node standardAvatar = ...;
> >     Node user = ...;
> >     Node library = user.getNode("library");
> >     Node avatar = library.addNode("avatar", "nt:linkedFile");
> >     avatar.setProperty("jcr:content", standardAvatar.getNode
> > ("jcr:content"));
> >     library.save();
> >
> > > jcr:content is of type nt:base and how can we define that it has a
> > property
> > > "image" which contains Binary data. Or shall I directly add "image"
> > property
> > > to blog:avator type like
> > >
> > > [blog:avatar] > nt:file,mix:referenceable
> > > - image (binary) mandatory primary
> >
> > No. You should instead use the standard nt:resource type as the
> > jcr:content node of a file and store the image data as
> > jcr:content/jcr:data as shown above.
> >
> > If you want to, you can extend the nt:resource type to contain
> > image-specific information like size and possible thumbnails:
> >
> >     [blog:image] > nt:resource
> >     - width (long)
> >     - height (long)
> >     + thumbnails (nt:folder)
> >
> > BR,
> >
> > Jukka Zitting
> >
>

Re: How to start thinking in JCR

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
Hi,
     I changed the Node structure as following according to the discussion
and tried to register them in the repository. Here are some of the problems
I came across.

Grammer for CND notation defines a property of a Node type as

property_def ::= "-" property_name [property_type_decl]
                 [default_values] [attributes]
                 [value_constraints]
property_name ::= string

Does all properties have to have a namespace prefix ? When I tried
to register the node types using the CompactNodeTypeDefReader it
gave an error caused by "UnknownPrefixException".

It also said that if I define the autocreated attribute for a childnode
I should define the default type for them which is of cource reasonable.

Like Node class's hasNode() method is there convinient methods to check
whether a namespace prefix is already registered ? and to check whether
a Node Type is already registed ? I didn't find such methods in
NodeTypeManager or NamespaceRegistry Interfaces of JCR. I used the
NodeTypeManagerImpl which inplements the JackrabbitNodeTypeManager
Interface.

But in the mailing list
// only register the type if it does not yet exist
    if (!manager.hasNodeType("myfile"))
is used to check this. Is that method not available in Jackrabbit 1.0 ?

To create a the repository I used the TransientRepository class which
created
me a default repository configuration file. But if I am using JNDI binding
do I have to create a repository.xml by my self ? Is there a way to specify
to
create a default configuration ?

Where can I find contrib/compact-nt tools ?

I really appreciate your comments. Thank you in advance.

BR,
Nandana


----------------------------------------------------- Node Structure
-------------------------------------------------------

/blogRoot [nt:folder]
/blogRoot/user [blog:user]
/blogRoot/user/blogSpace [nt:folder]
/blogRoot/user/blogSpace/<yyyy> [nt:folder]
/blogRoot/user/blogSpace/<yyyy>/<mm> [nt:folder]
/blogRoot/user/blogSpace/<yyyy>/<mm>/blogEntry [blog:blogEntry]
/blogRoot/user/blogSpace/<yyyy>/<mm>/blogEntry/comment [blog:Comment]
/blogRoot/user/library [nt:folder]
/blogRoot/user/libray/avatar [nt:file]
/<libray> [nt:folder]

-------------------------------------------   CND Notation for custom
types   -------------------------------------


<blog = 'http://jackrabbit.apache.org/jackrabbit-jcr-demo/1.0'>
<nt =  ... >
<jcr =  ... >


[blog:user] > mix:referenceable
- blog:nickname  (string) mandatory
- blog:email  (string) mandatory
- blog:password (string) mandatory
+ blog:library (nt:folder) =nt:folder mandatory autocreated
+ blog:blogSpace (nt:folder) =nt:folder mandatory autocreated


[blog:blogEntry] > nt:hierarchyNode, mix:referenceable
- blog:title (string) mandarory primary
- blog:content (string) mandatory
- blog:rate (long)
+ blog:attachments (nt:folder) =nt:folder mandatory autocreated

[blog:comment]
- blog:content (string) mandatory primary
- blog:commenter (reference ) mandatory  < blog:user

-----------------------------------------------------------   Stack trace
-----------------------------------------------------

org.apache.jackrabbit.core.nodetype.compact.ParseException: Error while
parsing 'nickname'
    at org.apache.jackrabbit.core.nodetype.compact.Lexer.fail(Lexer.java
:146)
    at
org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.toQName
(CompactNodeTypeDefReader.java:635)
    at
org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.doPropertyDefinition
(CompactNodeTypeDefReader.java:373)
    at
org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.doItemDefs
(CompactNodeTypeDefReader.java:331)
    at
org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.parse(
CompactNodeTypeDefReader.java:208)
    at org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader
.<init>(CompactNodeTypeDefReader.java:165)
    at org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader
.<init>(CompactNodeTypeDefReader.java:150)
    at nandana.jackrabbit.example1.NodeStructure.RegisterCustomNodeTypes(
NodeStructure.java:94)
    at nandana.jackrabbit.example1.NodeStructure.main(NodeStructure.java:58)
Caused by: org.apache.jackrabbit.name.UnknownPrefixException:
    at org.apache.jackrabbit.name.QName.fromJCRName(QName.java:596)
    at
org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader.toQName
(CompactNodeTypeDefReader.java:630)
    ... 7 more
Exception in thread "main" java.lang.NullPointerException
    at nandana.jackrabbit.example1.NodeStructure.RegisterCustomNodeTypes(
NodeStructure.java:101)
    at nandana.jackrabbit.example1.NodeStructure.main(NodeStructure.java:58)

















On 3/28/07, Jukka Zitting <ju...@gmail.com> wrote:
>
> Hi,
>
> On 3/29/07, Nandana Mihindukulasooriya <na...@gmail.com> wrote:
> > I should thank Brian, Xin and Jukka a lot for their valuable feedbacks
> > and I was able to understand lot of things when I went through the
> > JSR-170 again after reading the feedbacks.
>
> Excellent, thanks again for your efforts. Comments below...
>
> > Now we will create users using their unique user IDs like
> >
> > Node root = session.getRootNode();
> > Node user = root.addNode("uniqueUserID","blog:user");
> >
> > To avoid uniqueUserID conflit with other root's child nodes ( which are
> not
> > user nodes), can we use a namespace prefix as "id:uniqueID" with <id =
> > http://... >.
>
> Namespaces are a good way to avoid naming conflicts, but in this case
> an even better way would be to create your own "application root node"
> like /blog:root like the one you propose below. Such a root node
> nicely separates the blog content from any other application you may
> want to store in the same workspace. It also makes it easy to limit
> searches to just that subtree instead of including for example the
> whole /jcr:system tree.
>
> Also, I would encourage you to use a username or even the real name of
> the user as the node name instead of a numeric or some other abstract
> identifier.
>
> Thus the code would be:
>
>     Node root = session.getRootNode().getNode("blog:root");
>     Node user = root.addNode(username,"blog:user");
>
> > can we add something like this to root node to avoid non-unique userIDs
> ?
> >
> >     ChildNodeDefinition
> >     Name *
> >     RequiredPrimaryTypes UNDEFINED
> >     ...
> >     SameNameSiblings false
>
> The root node definition in Jackrabbit is essentially equivalent to
> nt:unstructured, so you can already add whatever child nodes you want
> to it without modifying the type definition.
>
> > If we can, how can we define it ? and is ItemExistsException throwed
> > immediately or on save in jackrabbit implementation of jcr ?
> > If we can't is there any other way to prevent it ?
>
> Node types can be registered using the CND or XML node type definition
> formats and the JackrabbitNodeTypeManager extension interface found in
> the jackrabbit-api component.
>
> Generally you shouldn't rely on an JCR implementation to perform
> consistency checks before the save() call. There are even many full
> consistency checks that can logically not be performed before the
> save() call.
>
> > or can I make a one root note child like this and define it not to have
> > sameNameSiblings.
> >
> > [blog:blog]
> >     - * [blog:user]
> >     - library [nt:folder] mandatory autocreated
>
> Such an approach would be my preferred alternative. You can't easily
> constraint the repository root node not to have children with same
> names, but you can quite easily enforce that in your application.
>
> As to the blog:blog node type, again I would prefer the standard
> nt:folder type. I'd also place the image library under a separate
> "content root" since it could very well be used by other applications
> as well. The content tree would look something like this:
>
>     /blog:blog [nt:folder]
>     /blog:blog/...
>     /blog:library [nt:folder]
>     /blog:library/...
>
> You can initialize your application like this (assuming you've already
> set up the namespaces):
>
>     Session session = ...;
>     Node root = session.getRootNode();
>     if (!root.hasNode("blog:blog")) {
>         root.addNode("blog:blog", "nt:folder");
>     }
>     if (!root.hasNode("blog:library")) {
>         root.addNode("blog:library", "nt:folder");
>     }
>     session.save();
>
> > As blogspace is of type nt:folder which has a child node definition,
> >
> >     ChildNodeDefinition
> >     Name *
> >     RequiredPrimaryType[nt:hierarchyNode]
> >
> > it can in turn have children of type nt:folder as nt:folder is
> a  subtype of
> > nt:hierarchyNode. So both <yyyy> and <mm> would be nodes of type
> nt:folder.
>
> Exactly.
>
> > So we can use,
> >
> > Node blogSpace = user.getNode("blogSpace");
> > Node year = blogspace.addNode("2007","nt:folder");
> > Node month = year.addNode("03","nt:folder");
> >
> > Is there a way to create a node with intermediate created automatically
> ?
> > If there is a way, how can we declare the types of intermediate nodes ?
> > Javadoc says it throws a PathNotFoundException if we try to create a
> > node without creating intermediate nodes.
>
> There's no such way, you need to handle that in your application.
>
>     Node blogSpace = ...;
>     if (!blogSpace.hasNode("year")) {
>         blogSpace.addNode("year", "nt:folder");
>         blogSpace.save();
>     }
>     Node year = blogSpace.getNode("year");
>     if (!year.hasNode("month")) {
>         year.addNode("month", "nt:folder");
>         year.save();
>     }
>     Node month = year.getNode("month");
>
> Note that the above code has a slight chance of race conditions if two
> sessions attempt to create the same intermediate nodes at the same
> time. You can either proactively prevent it by making the blogSpace
> node lockable and using JCR locks, or you can catch the concurrent
> modification exception and recover by retrying the operation. Since
> the chance of collisions is so small, I would go with the latter
> option.
>
> > So we have to come with a way to name the blog entries. Title may not be
> a
> > good candidate because they may white spacses and '.', '/', ':', '[',
> ']', '*',
> > ''', '"' charactors. Would a simple sequential numbering work ? Is there
> a better
> > way to handle this ?
>
> Generally a somewhat meaningful name is preferred over a sequence
> number. It makes administration much easier and also gives a nice
> URL-to-path mapping for web applications. I would go for a solution
> that either allows the user to specify the node name or uses a
> "simplifies" title as the node name. Many existing blog applications
> (for example WordPress) already use a "simplification" algorithm that
> turns title strings into valid URL path components. A similar solution
> would be perfect here as well.
>
> You would still store the full title as a normal string property to
> avoid losing data.
>
> > Node blogEntry = month.addNode("01","blog:blogEntry");
> > blogEntry.setProperty("content","my first blog entry");
> >
> > As blogEntry is a subtype of nt:hierarchyNode, I would be able to use
> > jcr:created property to get the created date of the blog.
>
> Exactly.
>
> > To add an image attachment,
> >
> > Node attachments = blogEntry.getNode("attachments");
> > Node linkedFile = attachments.addNode("attachment01","nt:linkedFile");
> > linkedFile.setProperty("jcr:content",root.getNode("library/xxx/yyy"));
> >
> > jcr:content property of the  nt:linkedFile  type  is of type reference.
>
> Perfect. Note that the jcr:content reference of an nt:linkedFile node
> should probably point to the jcr:content resource node of another file
> instead of the file node itself.
>
> > To add a Comment
> >
> > Node comment = blogEntry.addNode("01","blog:comment");
> > comment.setProperty("content","my first comment");
> > comment.setProperty("commenter", root.getNode("commenterID"));
>
> Exactly.
>
> > To add a avator to a user,
> >
> > Node library = root.getNode("library");
> > Node manAvatar = library.addNode("manAvator","blog:avatar");
> > Node content = manAvatar.getNode("jcr:content");
> > content.setProperty("image",imageInputStream);
> >
> > user.setProperty("avatar",manAvator);
>
> I think you'd be better of again using the standard nt:hierarchyNode
> model here instead of custom types. I would define a "personal
> library" folder for each user and place the avatar image there as
> either a local nt:file or as a nt:linkedFile that refers to some image
> in the global image library. A reserved name would be used for the
> avatar image, but other files could also be stored in this personal
> library folder. Using the standard node types allows you for example
> to use the existing WebDAV servlet classes from jackrabbit-jcr-server
> to serve the content in a web application. As an extra bonus you'd
> even get PUT support for free for remote clients to update the
> content!
>
>     [blog:user]
>     ....
>     + library (nt:folder) mandatory autocreated
>
> Adding a custom avatar would be:
>
>     Node user = ...;
>     Node library = user.getNode("library");
>     Node avatar = library.addNode("avatar", "nt:file");
>     avatar.addNode("jcr:content", "nt:resource");
>     avatar.setProperty("jcr:content/jcr:mimeType", "image/gif");
>     avatar.setProperty("jcr:content/jcr:lastModified",
> Calendar.getInstance());
>     avatar.setProperty("jcr:content/jcr:data", ...);
>     library.save();
>
> Adding a standard avatar from the global image library would be:
>
>     Node standardAvatar = ...;
>     Node user = ...;
>     Node library = user.getNode("library");
>     Node avatar = library.addNode("avatar", "nt:linkedFile");
>     avatar.setProperty("jcr:content", standardAvatar.getNode
> ("jcr:content"));
>     library.save();
>
> > jcr:content is of type nt:base and how can we define that it has a
> property
> > "image" which contains Binary data. Or shall I directly add "image"
> property
> > to blog:avator type like
> >
> > [blog:avatar] > nt:file,mix:referenceable
> > - image (binary) mandatory primary
>
> No. You should instead use the standard nt:resource type as the
> jcr:content node of a file and store the image data as
> jcr:content/jcr:data as shown above.
>
> If you want to, you can extend the nt:resource type to contain
> image-specific information like size and possible thumbnails:
>
>     [blog:image] > nt:resource
>     - width (long)
>     - height (long)
>     + thumbnails (nt:folder)
>
> BR,
>
> Jukka Zitting
>

Re: How to start thinking in JCR

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On 3/29/07, Nandana Mihindukulasooriya <na...@gmail.com> wrote:
> I should thank Brian, Xin and Jukka a lot for their valuable feedbacks
> and I was able to understand lot of things when I went through the
> JSR-170 again after reading the feedbacks.

Excellent, thanks again for your efforts. Comments below...

> Now we will create users using their unique user IDs like
>
> Node root = session.getRootNode();
> Node user = root.addNode("uniqueUserID","blog:user");
>
> To avoid uniqueUserID conflit with other root's child nodes ( which are not
> user nodes), can we use a namespace prefix as "id:uniqueID" with <id =
> http://... >.

Namespaces are a good way to avoid naming conflicts, but in this case
an even better way would be to create your own "application root node"
like /blog:root like the one you propose below. Such a root node
nicely separates the blog content from any other application you may
want to store in the same workspace. It also makes it easy to limit
searches to just that subtree instead of including for example the
whole /jcr:system tree.

Also, I would encourage you to use a username or even the real name of
the user as the node name instead of a numeric or some other abstract
identifier.

Thus the code would be:

    Node root = session.getRootNode().getNode("blog:root");
    Node user = root.addNode(username,"blog:user");

> can we add something like this to root node to avoid non-unique userIDs ?
>
>     ChildNodeDefinition
>     Name *
>     RequiredPrimaryTypes UNDEFINED
>     ...
>     SameNameSiblings false

The root node definition in Jackrabbit is essentially equivalent to
nt:unstructured, so you can already add whatever child nodes you want
to it without modifying the type definition.

> If we can, how can we define it ? and is ItemExistsException throwed
> immediately or on save in jackrabbit implementation of jcr ?
> If we can't is there any other way to prevent it ?

Node types can be registered using the CND or XML node type definition
formats and the JackrabbitNodeTypeManager extension interface found in
the jackrabbit-api component.

Generally you shouldn't rely on an JCR implementation to perform
consistency checks before the save() call. There are even many full
consistency checks that can logically not be performed before the
save() call.

> or can I make a one root note child like this and define it not to have
> sameNameSiblings.
>
> [blog:blog]
>     - * [blog:user]
>     - library [nt:folder] mandatory autocreated

Such an approach would be my preferred alternative. You can't easily
constraint the repository root node not to have children with same
names, but you can quite easily enforce that in your application.

As to the blog:blog node type, again I would prefer the standard
nt:folder type. I'd also place the image library under a separate
"content root" since it could very well be used by other applications
as well. The content tree would look something like this:

    /blog:blog [nt:folder]
    /blog:blog/...
    /blog:library [nt:folder]
    /blog:library/...

You can initialize your application like this (assuming you've already
set up the namespaces):

    Session session = ...;
    Node root = session.getRootNode();
    if (!root.hasNode("blog:blog")) {
        root.addNode("blog:blog", "nt:folder");
    }
    if (!root.hasNode("blog:library")) {
        root.addNode("blog:library", "nt:folder");
    }
    session.save();

> As blogspace is of type nt:folder which has a child node definition,
>
>     ChildNodeDefinition
>     Name *
>     RequiredPrimaryType[nt:hierarchyNode]
>
> it can in turn have children of type nt:folder as nt:folder is a  subtype of
> nt:hierarchyNode. So both <yyyy> and <mm> would be nodes of type nt:folder.

Exactly.

> So we can use,
>
> Node blogSpace = user.getNode("blogSpace");
> Node year = blogspace.addNode("2007","nt:folder");
> Node month = year.addNode("03","nt:folder");
>
> Is there a way to create a node with intermediate created automatically ?
> If there is a way, how can we declare the types of intermediate nodes ?
> Javadoc says it throws a PathNotFoundException if we try to create a
> node without creating intermediate nodes.

There's no such way, you need to handle that in your application.

    Node blogSpace = ...;
    if (!blogSpace.hasNode("year")) {
        blogSpace.addNode("year", "nt:folder");
        blogSpace.save();
    }
    Node year = blogSpace.getNode("year");
    if (!year.hasNode("month")) {
        year.addNode("month", "nt:folder");
        year.save();
    }
    Node month = year.getNode("month");

Note that the above code has a slight chance of race conditions if two
sessions attempt to create the same intermediate nodes at the same
time. You can either proactively prevent it by making the blogSpace
node lockable and using JCR locks, or you can catch the concurrent
modification exception and recover by retrying the operation. Since
the chance of collisions is so small, I would go with the latter
option.

> So we have to come with a way to name the blog entries. Title may not be a
> good candidate because they may white spacses and '.', '/', ':', '[', ']', '*',
> ''', '"' charactors. Would a simple sequential numbering work ? Is there a better
> way to handle this ?

Generally a somewhat meaningful name is preferred over a sequence
number. It makes administration much easier and also gives a nice
URL-to-path mapping for web applications. I would go for a solution
that either allows the user to specify the node name or uses a
"simplifies" title as the node name. Many existing blog applications
(for example WordPress) already use a "simplification" algorithm that
turns title strings into valid URL path components. A similar solution
would be perfect here as well.

You would still store the full title as a normal string property to
avoid losing data.

> Node blogEntry = month.addNode("01","blog:blogEntry");
> blogEntry.setProperty("content","my first blog entry");
>
> As blogEntry is a subtype of nt:hierarchyNode, I would be able to use
> jcr:created property to get the created date of the blog.

Exactly.

> To add an image attachment,
>
> Node attachments = blogEntry.getNode("attachments");
> Node linkedFile = attachments.addNode("attachment01","nt:linkedFile");
> linkedFile.setProperty("jcr:content",root.getNode("library/xxx/yyy"));
>
> jcr:content property of the  nt:linkedFile  type  is of type reference.

Perfect. Note that the jcr:content reference of an nt:linkedFile node
should probably point to the jcr:content resource node of another file
instead of the file node itself.

> To add a Comment
>
> Node comment = blogEntry.addNode("01","blog:comment");
> comment.setProperty("content","my first comment");
> comment.setProperty("commenter", root.getNode("commenterID"));

Exactly.

> To add a avator to a user,
>
> Node library = root.getNode("library");
> Node manAvatar = library.addNode("manAvator","blog:avatar");
> Node content = manAvatar.getNode("jcr:content");
> content.setProperty("image",imageInputStream);
>
> user.setProperty("avatar",manAvator);

I think you'd be better of again using the standard nt:hierarchyNode
model here instead of custom types. I would define a "personal
library" folder for each user and place the avatar image there as
either a local nt:file or as a nt:linkedFile that refers to some image
in the global image library. A reserved name would be used for the
avatar image, but other files could also be stored in this personal
library folder. Using the standard node types allows you for example
to use the existing WebDAV servlet classes from jackrabbit-jcr-server
to serve the content in a web application. As an extra bonus you'd
even get PUT support for free for remote clients to update the
content!

    [blog:user]
    ....
    + library (nt:folder) mandatory autocreated

Adding a custom avatar would be:

    Node user = ...;
    Node library = user.getNode("library");
    Node avatar = library.addNode("avatar", "nt:file");
    avatar.addNode("jcr:content", "nt:resource");
    avatar.setProperty("jcr:content/jcr:mimeType", "image/gif");
    avatar.setProperty("jcr:content/jcr:lastModified", Calendar.getInstance());
    avatar.setProperty("jcr:content/jcr:data", ...);
    library.save();

Adding a standard avatar from the global image library would be:

    Node standardAvatar = ...;
    Node user = ...;
    Node library = user.getNode("library");
    Node avatar = library.addNode("avatar", "nt:linkedFile");
    avatar.setProperty("jcr:content", standardAvatar.getNode("jcr:content"));
    library.save();

> jcr:content is of type nt:base and how can we define that it has a property
> "image" which contains Binary data. Or shall I directly add "image" property
> to blog:avator type like
>
> [blog:avatar] > nt:file,mix:referenceable
> - image (binary) mandatory primary

No. You should instead use the standard nt:resource type as the
jcr:content node of a file and store the image data as
jcr:content/jcr:data as shown above.

If you want to, you can extend the nt:resource type to contain
image-specific information like size and possible thumbnails:

    [blog:image] > nt:resource
    - width (long)
    - height (long)
    + thumbnails (nt:folder)

BR,

Jukka Zitting

Re: How to start thinking in JCR

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
Hi,
   I should thank Brian, Xin and Jukka a lot for their valuable feedbacks
and I was able
to understand lot of things when I went through the JSR-170 again after
reading the feedbacks.
So I modified the CND,

    /user
    /user/blogSpace
    /user/blogSpace/<yyyy>/<mm>
    /user/blogSpace/<yyyy>/<mm>/blogEntry
    /user/blogSpace/<yyyy>/<mm>/blogEntry/comment
    /library
    /library/images
    /library/images/<avatar>

------------------------------------------------------------------------------------------------------------------------------

<blog = 'http://jackrabbit.apache.org/jackrabbit-jcr-demo/1.0'>
<nt =  'http://www.jcp.org/jcr/nt/1.0' >
<jcr =  'http://www.jcp.org/jcr/1.0' >


[blog:user] > mix:referenceable
    - nickname  (string) mandatory
    - email  (string) mandatory
    - password (string) mandatory
    - avatar (reference) < blog:avatar
    + blogSpace [nt:folder] mandatory autocreated


[blog:blogEntry] > nt:hierarchyNode, mix:referenceable
    - content (string) mandatory primary
    - rate (long)
    + attachments (nt:folder) mandatory autocreated

[blog:comment]
    - content (string) mandatory primary
    - commenter (reference ) mandatory  < blog:user

[blog:avatar] > nt:file, mix:referenceable

blogspace , <yyyy> , <mm> , library, images will be type of [nt:folder]



------------------------------------------------------------------------------------------------------------------------------

Now we will create users using their unique user IDs like

Node root = session.getRootNode();
Node user = root.addNode("uniqueUserID","blog:user");

To avoid uniqueUserID conflit with other root's child nodes ( which are not
user
nodes ), can we use a namespace prefix as "id:uniqueID" with <id =
http://... > .

can we add something like this to root node to avoid non-unique userIDs ?

    ChildNodeDefinition
    Name *
    RequiredPrimaryTypes UNDEFINED
    ...
    SameNameSiblings false

If we can, how can we define it ? and is ItemExistsException throwed
immediately
or on save in jackrabbit implementation of jcr ?
If we can't is there any other way to prevent it ?

or can I make a one root note child like this and define it not to have
sameNameSiblings.

[blog:blog]
    - * [blog:user]
    - library [nt:folder] mandatory autocreated


-------------------------------------------------------------------------------------------------------------------------------

As blogspace is of type nt:folder which has a child node definition,

    ChildNodeDefinition
    Name *
    RequiredPrimaryType[nt:hierarchyNode]

it can in turn have children of type nt:folder as nt:folder is a  subtype of
nt:hierarchyNode. So both <yyyy> and <mm> would be nodes of type nt:folder.
So we can use,

Node blogSpace = user.getNode("blogSpace");
Node year = blogspace.addNode("2007","nt:folder");
Node month = year.addNode("03","nt:folder");

Is there a way to create a node with intermediate created automatically ?
If there is a way, how can we declare the types of intermediate nodes ?
Javadoc
says it throws a PathNotFoundException if we try to create a node without
creating
intermediate nodes.

---------------------------------------------------------------------------------------------------------------------------

So we have to come with a way to name the blog entries. Title may not be a
good
candidate because they may white spacses and '.', '/', ':', '[', ']', '*',
''',
'"' charactors. Would a simple sequential numbering work ? Is there a better
way
to handle this ?

Node blogEntry = month.addNode("01","blog:blogEntry");
blogEntry.setProperty("content","my first blog entry");

As blogEntry is a subtype of nt:hierarchyNode, I would be able to use
jcr:created
property to get the created date of the blog.

To add an image attachment,

Node attachments = blogEntry.getNode("attachments");
Node linkedFile = attachments.addNode("attachment01","nt:linkedFile");
linkedFile.setProperty("jcr:content",root.getNode("library/xxx/yyy"));

jcr:content property of the  nt:linkedFile  type  is of type reference.

---------------------------------------------------------------------------------------------------------------------------

To add a Comment

Node comment = blogEntry.addNode("01","blog:comment");
comment.setProperty("content","my first comment");
comment.setProperty("commenter", root.getNode("commenterID"));


-----------------------------------------------------------------------------------------------------------------------------


To add a avator to a user,

Node library = root.getNode("library");
Node manAvatar = library.addNode("manAvator","blog:avatar");
Node content = manAvatar.getNode("jcr:content");
content.setProperty("image",imageInputStream);

user.setProperty("avatar",manAvator);

jcr:content is of type nt:base and how can we define that it has a property
"image"
which contains Binary data. Or shall I directly add "image" property to
blog:avator
type like

[blog:avatar] > nt:file,mix:referenceable
- image (binary) mandatory primary



BR,
Nandana

Re: How to start thinking in JCR

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On 3/27/07, Nandana Mihindukulasooriya <na...@gmail.com> wrote:
> Nope,  Same image will not be attached to multiple Blog Entires. But if it
> is the case, as I understood I should use property of reference type in the
> blog entry which references to a image attachment. Is that the way to handle
> it ?

Yes. Such solutions are typically called image or document (or even
digital asset) libraries in content management systems. In a JCR
content repository such a library could conveniently be managed as a
separate content tree, like /my:library.

A good solution would be to make the image library consist of standard
nt:folder and nt:file nodes to make it easily manageable. You can then
for example mount the library subtree as a standard WebDAV folder
using jackrabbit-jcr-server as the server. And since the nt:resource
nodes within nt:files are referenceable, you can readily link to the
images and other resources within the library.

> 1.) In naming node types and properties, do we follow the naming conventions
> used in Java ? Eg. myFristType

That's the precedent set by the JCR spec (for example
nt:hierarchyNode), so it's a good convention to follow.

> 2.) What is purpose mixin node type ?  Purpose of primary node is to define
> the structure of the node as I understood. What is the advantage of adding
> some properties or child nodes  via mixin types to a node ?

The Java class/interface model mentioned by alartin is a good way to
look at it, but there are two important differences. The first one is
that Jackrabbit supports multiple inheritance, i.e. a primary type can
inherit any number of both primary and mixin types. The second one is
that you can dynamically add or remove mixin types of a node.

I usually think of the primary type of a node as the primary
definition of that node. The node should be perfectly usable with no
dynamically added mixin types (note that the primary type can include
mixin types like mix:referenceable if needed).

Mixin types on the other hand can be used for adding extra "features"
to a node. Such features would typically be orthogonal to the main
purpose of the node. For example, if I have a standard nt:folder
structure, I might decide that I want to make some folder
referenceable, lockable, or versionable in which case I'd simply add
the respective mixin type to that node. The folder would still work
just as before, with just the extra functionality added.

> 3.) What is the purpose of primary item of a node type?

As alartin mentioned, it is mostly used to as a guide to applications.
For example jackrabbit-jcr-server knows how to follow primary item
definitions to decide which property to serve as the primary content
of a node even though the implementation has little or no built-in
knowledge of the node type semantics.

> 4.) In a property definition, in Required Type, what does NAME, PATH types
> mean ?

They are for storing JCR item names and paths in a way that is
independent of particular namespace mappings. For example a path
/foo:name would become /bar:name if the "foo" namespace mapping is
modified. If the path was just stored as a "/foo:name" string, then it
would become invalid when the prefix changes, but if it was stored as
a PATH property, then Property.getString() on it would actually return
"/bar:name" with the new prefix.

> In CND notation,
>
> <blog = 'http://jackrabbit.apache.org/jackrabbit-jcr-demo/1.0'>
> <mix = 'http://www.jcp.org/jcr/mix/1.0'>
>
> [blog:user] > mix:referenceable
> -          blog:userID   (long) mandatory

You don't really need these ID numbers, they are likely a result of
the earlier normalization process. In JCR all content items are always
uniquely identified by their paths, and making a node referenceable
adds a persistent UUID identifier that won't change even if the node
is moved around.

> + blog:year  [blog:year] multiple

Having custom node types for the intermediate nodes isn't really
necessary, and could even be seen as detrimental. I would instead use
a standard nt:folder hierarchy, with the added benefit of making the
content tree more "familiar" to generic JCR tools. Something like
this:

    + blog:content [nt:folder] mandatory autocreated

Your application can then create the required yyyy/mm subfolders as
needed. This approach would allow you to later change the substructure
if needed.

> [blog:blogEntry]
> -          blog:blogEntryID (long) mandatory

Again, no need for the explicit ID number. If the entries need to be
referenceable (would be a good idea for example to support unique
identifiers in syndication feeds), then mix:referenceable is a better
solution. To go with the above nt:folder solution I would also make
the blog entries extend nt:hierarchyNode.

    [blog:blogEntry] > nt:hierarchyNode, mix:referenceable

> -          blog:content (string) mandatory

I would mark this as the primary item:

    - blog:content (string) mandatory primary

> -          blog:image (binay) multiple

Instead of a single binary property it would probably be better to use
either a single nt:resource child node for the image or an nt:folder
subtree that could support multiple attachments and even links
(nt:linkedFile) to a document library as mentioned above. Something
like this:

    + blog:attachments (nt:folder) mandatory autocreated

> -          blog:dateCreated (date) mandatory

If you made the node entries extend nt:hierarchyNode as mentioned
above, you would get the standard autocreated jcr:created property for
free.

> [blog:comment]
> -          blog:commentID (long) mandatory

Same as with the blog entries, drop the artificial identifier for
mix:referenceable and use nt:hierarchyNode:

    [blog:comment] > nt:hierarchyNode, mix:referenceable

BR,

Jukka Zitting

Re: How to start thinking in JCR

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
Hi,

On 3/24/07, Brian Thompson <el...@gmail.com> wrote:
>
> Comments interleaved below:
>
> Oh, one other thing:  In your model, do you ever expect the same image
> to be attached to multiple BlogEntries?


Nope,  Same image will not be attached to multiple Blog Entires. But if it
is the case, as I understood I should use property of reference type in the
blog entry which references to a image attachment. Is that the way to handle
it ?


> I went through the Node Type sections of the Jackrabbit site and also 6.7Node Types of the JSR 170 specification. As I understood,

A node type defines the  Child nodes and properties it may ( or must ) have.

Primary node type must be subtype of either primary or a mixin type and
mixin type may have a super type and it is not a must.

I have few questions and some of them may be obsolete. But I listed them
down as it is always better have a discussion and get things clarified.

1.) In naming node types and properties, do we follow the naming conventions
used in Java ?
Eg. myFristType

2.) What is purpose mixin node type ?  Purpose of primary node is to define
the structure of the node as I understood. What is the advantage of adding
some properties or child nodes  via mixin types to a node ?

3.) What is the purpose of primary item of a node type?

4.) In a property definition, in Required Type, what does NAME, PATH types
mean ?

5.) Is int supported as a property type ? It is not listed under  the
property_type in the grammer.

6.) How to we constraint a property of a node to be unique ( like a primary
key in RDBMS ) ?



As you proposed, if we change the hierarchy like this,

                - Users
                         -  Year
                                  - Month

      - Date

             -  Blog Entry

                       -  Comment

                       -  Rate

                       -  Image Attachment



In CND notation,

<blog = 'http://jackrabbit.apache.org/jackrabbit-jcr-demo/1.0'>

<mix = 'http://www.jcp.org/jcr/mix/1.0'>

[blog:user] > mix:referenceable

-          blog:userID   (long) mandatory

-          blog:nickName  (string) mandatory

-          blog:email  (string) mandatory

-          blog:password (string) mandatory

+ blog:year  [blog:year] multiple


[blog:year]

-          blog:year  (long) mandatory

+   blog:month  [blog:month] multiple


[blog:date]

-          blog:date (date)

+  blog:blogEntry [blog:blogEntry] multiple


[blog:blogEntry]

-          blog:blogEntryID (long) mandatory

-          blog:content (string) mandatory

-          blog:image (binay) multiple

-          blog:rate (long)

-          blog:dateCreated (date) mandatory

+    blog:comment [blog:comment] multiple



[blog:comment]

-          blog:commentID (long) mandatory

-          commenterID (reference) mandatory  < blog:user

-          blog:content (string) mandatory

-          blog:dateCreated (date) mandatory

Re: How to start thinking in JCR

Posted by Brian Thompson <el...@gmail.com>.
Comments interleaved below:


Nandana Mihindukulasooriya wrote:
> On 3/23/07, Brian Thompson <el...@gmail.com> wrote:
> Yes, this a very simplified version how I keep the blog related to the 
> mblog
> application which I'm currently involved. There I use a RDBMS, so it was
> designed with those guidelines in mind. What are the things one should
> consider if migrating from RDBMS to JCR.  What are the common pitfalls ? So
> if I put it to in to a hierarchy like this
> 
>            - Users
>                     -   BlogEntry
>                           - Comment
>                           -  Rate
>                           - Image Attachment
> 
>         or
>                 - Users
>                 - Year
>                       - Month
>                              - Date
>                                   - Blog Entry
>                                             - Comment
>                                             - Rate
>                                             - Image Attachment
> 
> Would this be a a good hierarchy ? What do I think when choosing a 
> hierarchy


Both of these hierarchies would work reasonably well.  Personally, I'd 
lean towards a slight modification on the second option as a way of 
organizing data instead of having (eventually) thousands of BlogEntry 
nodes as immediate children of the User.

I would put Year under User instead of alongside it, though:

- Users
     - Year
         - Month
             ...


> ? Choosing the correct hierarchy must make it easy to search and navigate
> and it would also increase the performance , isn't it ?
> 
> What are the other possible options I have ?
> 
> Under the first hierarchy referential integrity is automatically preserved,
> isn't it ? How do I preserve the integrity if I go to the second option ?


Both hierarchies (if you use my modification) preserve referential 
integrity; in my proposed model, you simply have to call 
Node.getParent() a couple of extra times.  With Years as siblings of 
Users instead of children of users, you'd have to include a reference to 
the User in the BlogEntry node.  Taking a look at the Node Types/Node 
Type Notation pages 
(http://jackrabbit.apache.org/doc/nodetype/index.html and 
http://jackrabbit.apache.org/doc/nodetype/cnd.html) should give you some 
ideas.

One other thing to look at is the mix:referenceable mixin type that 
Jackrabbit offers.  Reading up on it should give you some ideas on how 
to retrieve arbitrary blog entries.

Oh, one other thing:  In your model, do you ever expect the same image 
to be attached to multiple BlogEntries?

-Brian



> 
> Yes,  I would  like to change the  scope of the project  ( of course , 
> it is
> the mentor I think who can take and guide me to the those decisions )
> according to the discussions in the mailing list. As I am new to jackrabbit
> I will depend a lot on the jackrabbit community and I planning to do the
> project with the help of jackrabbit community. Anyway I am ready put a
> considerable  time to for the GSoc project and I will always keep a healthy
> communication with the community.
> 
> Thank you very much, I really appreciate your advices and the guidance.
> 
> BR,
> 
> Nandana

Re: How to start thinking in JCR

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
On 3/23/07, Brian Thompson <el...@gmail.com> wrote:
>
> Nice relational modeling - your data below would fit quite neatly into a
> database.  Keeping in mind that JCR nodes fall naturally into a tree
> structure, how are you thinking of organizing the nodes that will store
> your Users, BlogEntries, etc?


Yes, this a very simplified version how I keep the blog related to the mblog
application which I'm currently involved. There I use a RDBMS, so it was
designed with those guidelines in mind. What are the things one should
consider if migrating from RDBMS to JCR.  What are the common pitfalls ? So
if I put it to in to a hierarchy like this

            - Users
                     -   BlogEntry
                           - Comment
                           -  Rate
                           - Image Attachment

         or
                 - Users
                 - Year
                       - Month
                              - Date
                                   - Blog Entry
                                             - Comment
                                             - Rate
                                             - Image Attachment

Would this be a a good hierarchy ? What do I think when choosing a hierarchy
? Choosing the correct hierarchy must make it easy to search and navigate
and it would also increase the performance , isn't it ?

What are the other possible options I have ?


Also, do you have ideas on how to guarantee unique IDs for your data and
> maintain referential integrity?  In my mind, there are some obvious
> answers, but it may be more valuable for you as a learning exercise to
> ponder these questions a bit :)



Under the first hierarchy referential integrity is automatically preserved,
isn't it ? How do I preserve the integrity if I go to the second option ?


It might also be valuable to consider doing a different sort of example
> application.  When I started investigating Jackrabbit, I saw one or two
> articles (with code snippets) that used a simple blog application as the
> example to demonstrate basic Jackrabbit operations.


Yes,  I would  like to change the  scope of the project  ( of course , it is
the mentor I think who can take and guide me to the those decisions )
according to the discussions in the mailing list. As I am new to jackrabbit
I will depend a lot on the jackrabbit community and I planning to do the
project with the help of jackrabbit community. Anyway I am ready put a
considerable  time to for the GSoc project and I will always keep a healthy
communication with the community.

Good luck on your GSOC project!


Thank you very much, I really appreciate your advices and the guidance.

-Brian


BR,

Nandana

Nandana Mihindukulasooriya wrote:
> > Hi Xin,
> >             Thanks a lot for giving me the starting point. Those
> > discussions you started on your application are really valuable for me
> and
> > I'm learning a lot from them.
> >              As a start, If we consider only a simple blog first with
> least
> > features we have users, blog entries and images attached to blog
> entries,
> > comments and rating.
> >
> > Users has
> > 1.    User ID
> > 2.    Nick name
> > 3.    Email
> > 4.    Password
> >
> > Blog entry has
> > 1.    BlogEntryID
> > 2.    Owner  :  An existing user
> > 3.    Text Content
> > 4.    Image Attachments
> > 5.    Rate
> > 6.    Date created
> >
> > Image Attachment has
> > 1.    ImageID
> > 2.    BlogEntryID : Image should be related with exiting blog entry
> > 3.    Image : Binary Image
> >
> > Comment
> > 1.    CommentID
> > 2.    BlogEntryID : Comment should be related with existing blog entry
> > 3.    CommenterID : Comment should be made by existing user
> > 4.    Comment : A text comment
> > 5.    Date created
> >
> >              All the ids used here will have to be unique.  And the
> > specially mentioned fields must have referential integrity.
> >              I would like to have discussion on what are options I have
> > when I do object content mapping and what are the things I should
> consider
> > in more general context . If there are more options what are pros and
> cons.
> > I can spend some time on design phase as GSoc officially starts on April
> 9
> > and the date scheduled to start coding is May 28. Even though I would
> start
> > much before that, I would like to have a in-depth discussion as it would
> be
> > good for the new comers to the community.
> >
> > Thanks a lot,
> > Nandana
> >
>

Re: How to start thinking in JCR

Posted by Brian Thompson <el...@gmail.com>.
Nice relational modeling - your data below would fit quite neatly into a 
database.  Keeping in mind that JCR nodes fall naturally into a tree 
structure, how are you thinking of organizing the nodes that will store 
your Users, BlogEntries, etc?

Also, do you have ideas on how to guarantee unique IDs for your data and 
maintain referential integrity?  In my mind, there are some obvious 
answers, but it may be more valuable for you as a learning exercise to 
ponder these questions a bit :)

It might also be valuable to consider doing a different sort of example 
application.  When I started investigating Jackrabbit, I saw one or two 
articles (with code snippets) that used a simple blog application as the 
example to demonstrate basic Jackrabbit operations.

Good luck on your GSOC project!

-Brian



Nandana Mihindukulasooriya wrote:
> Hi Xin,
>             Thanks a lot for giving me the starting point. Those
> discussions you started on your application are really valuable for me and
> I'm learning a lot from them.
>              As a start, If we consider only a simple blog first with least
> features we have users, blog entries and images attached to blog entries,
> comments and rating.
> 
> Users has
> 1.    User ID
> 2.    Nick name
> 3.    Email
> 4.    Password
> 
> Blog entry has
> 1.    BlogEntryID
> 2.    Owner  :  An existing user
> 3.    Text Content
> 4.    Image Attachments
> 5.    Rate
> 6.    Date created
> 
> Image Attachment has
> 1.    ImageID
> 2.    BlogEntryID : Image should be related with exiting blog entry
> 3.    Image : Binary Image
> 
> Comment
> 1.    CommentID
> 2.    BlogEntryID : Comment should be related with existing blog entry
> 3.    CommenterID : Comment should be made by existing user
> 4.    Comment : A text comment
> 5.    Date created
> 
>              All the ids used here will have to be unique.  And the
> specially mentioned fields must have referential integrity.
>              I would like to have discussion on what are options I have
> when I do object content mapping and what are the things I should consider
> in more general context . If there are more options what are pros and cons.
> I can spend some time on design phase as GSoc officially starts on April 9
> and the date scheduled to start coding is May 28. Even though I would start
> much before that, I would like to have a in-depth discussion as it would be
> good for the new comers to the community.
> 
> Thanks a lot,
> Nandana
> 

Re: How to start thinking in JCR

Posted by Nandana Mihindukulasooriya <na...@gmail.com>.
Hi Xin,
             Thanks a lot for giving me the starting point. Those
discussions you started on your application are really valuable for me and
I'm learning a lot from them.
              As a start, If we consider only a simple blog first with least
features we have users, blog entries and images attached to blog entries,
comments and rating.

Users has
1.    User ID
2.    Nick name
3.    Email
4.    Password

Blog entry has
1.    BlogEntryID
2.    Owner  :  An existing user
3.    Text Content
4.    Image Attachments
5.    Rate
6.    Date created

Image Attachment has
1.    ImageID
2.    BlogEntryID : Image should be related with exiting blog entry
3.    Image : Binary Image

Comment
1.    CommentID
2.    BlogEntryID : Comment should be related with existing blog entry
3.    CommenterID : Comment should be made by existing user
4.    Comment : A text comment
5.    Date created

              All the ids used here will have to be unique.  And the
specially mentioned fields must have referential integrity.
              I would like to have discussion on what are options I have
when I do object content mapping and what are the things I should consider
in more general context . If there are more options what are pros and cons.
I can spend some time on design phase as GSoc officially starts on April 9
and the date scheduled to start coding is May 28. Even though I would start
much before that, I would like to have a in-depth discussion as it would be
good for the new comers to the community.

Thanks a lot,
Nandana

Re: How to start thinking in JCR

Posted by alartin <al...@gmail.com>.
Hi Nunny,

I think the first step is domain modelling, let others understand what you
want and which aspects you are most concerned about. The second step is
object cotent mapping(OCM), that is to say, how to present your domain
entities in a hierarchical structure as nodes and properties. Meanwhile, you
should think about node type definition.
I am starting a demo called "Ikkyu" from scratch with helps from Jukka and
other experts. So, please give your blog demo proposal here and let us
discuss about it.

Nunny wrote:
> 
>          I'm planning to do a jackrabbit-jcr-demo in the Google Summer of
> Code and one of the important deliverable of it would be the
> documentation.
> My plain is to raise questions and have discussions through out the
> project
> and grab the expertise of all the well experienced jackrabbit programmers
> in
> the mailing list and put it in to a documentation in a structured way so
> that a new comer won't have to go through all the mail archives to find
> the
> information.
> 
>         So I thought of starting from the very beginning. Say if we are
> using a relational database, we can model our data in business and their
> relationships in an ER or an EER diagram then convert in to relations and
> normalize them.  When we are using JCR what is the best approach for
> content
> modeling? How should one start content modeling? I should thank Xin and
> other developers for his discussion on content modeling, it is really
> beneficial to me too and I am learning lot of basic things from that
> discussion. I am following that discussion very carefully to learn things.
> But here I raised the question again to get a more general answer at a
> more
> basic level.
> 
>         I would really thankful if all the expert jackrabbit users can
> contribute so that I will be able to document all the important points you
> have gained through experience and it will be very useful to a new
> jackrabbit programmer.
> 
> 
> 
> Thank you in advance
> 
> Nandana
> 
> 

-- 
View this message in context: http://www.nabble.com/How-to-start-thinking-in-JCR-tf3452522.html#a9631679
Sent from the Jackrabbit - Users mailing list archive at Nabble.com.