Announcement Announcement Module
Collapse

Spring Modules forum decommissioned in favor of Spring Extensions

As the Spring Modules project has been replaced by the Spring Extensions (http://www.springsource.org/extensions) project, this forum has been decommissioned in favour of Spring Extensions one at:
http://forum.springsource.org/forumdisplay.php?f=44

Please see the Spring Extensions home page for a complete list of current projects in Java, .NET and ActionScript. You can also propose one if you want.

Cheers,
Costin Leau
SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
http://twitter.com/costinl
See more
See less
JSR-170 and Spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JSR-170 and Spring

    Hello.

    I have a requirement to work with JSR-170 (Java Content Repository) and I would like to know what alternatives are out there and how Spring can ease working with them and then commit the code to Spring Modules .

    The only open-source implementation available that I could find was jackrabbit(http://incubator.apache.org/jackrabbit/).

    Any suggestions about other implementations or requirements are welcomed

  • #2
    I'm looking into using the spec myself. As for implementations besides Jackrabbit:

    Magnolia:
    http://www.magnolia.info/en/magnolia.html

    I think Magnolia uses some of the code from Jackrabbit. They also have a few applications built on top of their repository. They also have code you can have a look at here: http://sourceforge.net/project/showf...group_id=86297

    Day
    http://www.day.com/

    Day contributed to the spec and has alot of resources on their site about JSR-170. I'm not sure if their implementation is open source.


    Also check out:

    Introducing the Java Content Repository API
    IBM Developworks
    http://www-128.ibm.com/developerwork...library/j-jcr/

    Catch Jackrabbit and the Java Content Repository API
    Artima
    http://www.artima.com/lejava/article...epository.html


    As for Spring, I'm sure if you were looking to build a CR, I see no reason why you couldn't use Spring to help you do that. At the very least, it seems the most typical way to access a Repository is to place it in JNDI, in which you can use Spring's JNDI support to assist you.

    I would also be interested in anyone's experience with JSR-170, especially if they were using Spring along with it.


    Keller

    Comment


    • #3
      Thanks for the info. Support for JSR-170 will soon be available through Spring Modules.

      Comment


      • #4
        Can you be a little more specific? What sort of "support" do you plan on adding?

        For example, I've been going through the spec this morning and it seems that Spring's JTA support would be very benificial if one were developing a transactional repository.


        Keller

        Comment


        • #5
          Indeed. The support resembles the orm.hibernate(3)/jdo packages - session factory, template, declarative transaction support and a local and jta transaction manager.
          The TM need a bit of work now - I have a version of a local TM but it's not very elegant. I have an a draft of the global TM but it's not yet finished.
          The rest however it's done and it works. I'll commit some code to the SM CVS by the middle of next week - time is the main concern here.

          Comment


          • #6
            Ofc, this means that the JSR-170 implementation needs to have transaction support and so far only jackrabbit has such a feature. Magnolia is a CMS not a JSR-170 implementation btw.
            They claim to support also "Jeiceira" which is a relatively new project that AFAIK, has no transactional support for JSR-170.
            After I'll finish the TM implementation for JackRabbit I plan to take a look at Jeiceira and add support for it also.

            Comment


            • #7
              Magnolia mentions on their home page that their CMS is "built on" JSR-170 in about three different places. I would assume you are making a distinction between CMSs that are applying the standard to an already existing product in order to allow access to their data in a standardized way versus a project like Jackrabbit which allows people to develop a fully compliant repository.

              Another thing I was thinking about was integrating Acegi with Jackrabbit in order to provide security framework for a repository.

              Also, in all the examples I've seen, the Repository object is using JNDI. I would think you could also just access the Repository through Spring and have the container handle the configuration, instanciation, etc.

              Have you had an opportunity to check in any code. I would be very interesting in having a look at it.


              Keller

              Comment


              • #8
                Thanks for the interest. I intend to commit the code this weekend on the cvs - I still have to finish some small things and add unit tests. I'll let you know on this thread.

                Security in Jackrabbit is bit of an issue - take a look at the mailing list - there is an interesting thread (including Ben Alex); they have done it through JAAS which is hard to bypass/hook up. I'm still thinking of a solution for this problem.

                Also, in all the examples I've seen, the Repository object is using JNDI. I would think you could also just access the Repository through Spring and have the container handle the configuration, instanciation, etc.
                The repository is JNDI independent. Don't worry, the current support does just that.

                Magnolia mentions on their home page that their CMS is "built on" JSR-170 in about three different places. I would assume you are making a distinction between CMSs that are applying the standard to an already existing product in order to allow access to their data in a standardized way versus a project like Jackrabbit which allows people to develop a fully compliant repository.
                The specifications (JSR-170) already has some implementations (JackRabbit and Jeceira); a product using this implementation is different from the implementation itself.

                Comment


                • #9
                  I've just committed the main part of the core to the Spring modules CVS:
                  https://springmodules.dev.java.net/s...ngmodules/jcr/
                  Check it out.

                  Comment


                  • #10
                    I like what i see

                    I have been using Magnolia a while now.

                    It is basically built on top of Jackrabbit.
                    I've customized it a little to make it more easy to use.
                    Looks great now, but preform horrible.
                    (We have a lot of changing content,
                    and building the cache for every change
                    is "killing" our server under load)

                    Now i dont know what to do. Would be cool if i could
                    export the content to a spring app with JSR-170 support.

                    Any good ideas, out there?

                    -Erik

                    Comment


                    • #11
                      There are quite a couple of solutions to your problem:
                      1. you can see if Magnolia doesn't already support such a feature and ask for it. I know Magnolia team is very responsive.
                      2. if the content is loaded inside the jackrabbit repository you can simply configure (using spring support for jsr-170 for example) your code to look at the repository and access it or export it through the JCR api.
                      3. use some JCR tools - there are some out there - to see your repository and extract the info from it.
                      Remember that one of the greatest strength of JSR-170 is that using the standardized API you can access the repository from web, command line applicatin or even a non-java environment.

                      Comment


                      • #12
                        how to config to support multiple workspance for spingmodules jcr?

                        When i study the springmodules jcr project and souce,i dont found how to config it to support multiple workspace?
                        Any suggestion?
                        Thx!

                        Comment


                        • #13
                          Multiple Workspaces with JCR

                          If you only have one workspace (or some fixed number of them) in your app, you can use dependency injection to manage them all (in your applicationContext.xml files, you'd create a JcrSessionFactory for each repsoitory/workspace/credentials combination, and create a corresponding JcrDaoSupport subclass for each of those JcrSessionFactory beans.

                          In my case, I've got a workspace for each user and that means I can't create them until the application is running and I have user accounts created. The system I'm working on solves the problem of how you do SpringModules JCR based access to workspaces created dynamically, while the application is running. I'm still working on my solution to this problem. When I confirm that it works for my app, I'm going to write a generalized example and some documentation, as I have time.

                          The way I've got it set up, there's two hierarchies: a repository-based hierarchy and a workspace-based hierarchy. The repository-based hierarchy is intended to be the "visible" outer layer of the system; this is where I implement an interface that is used by other parts of my application. The workspace-based hierarchy is used to actually perform the work of accessing Nodes in the repository's workspaces and is only used by the repository-based class hierarchy. Here's more detailed descriptions:

                          Class: AbstractJcrDao
                          Extends: Object
                          Implements: <none>
                          Description:
                          This class has several properties that will be used by subclasses: systemRepository, systemCredentials, requireTransactionalSession. All three can be set by dependency injection. In my app, I have only one user/pass, so this is a good place for me to keep the Credentials; if you have multiple users for your repository, you may want to put the credentials elsewhere. There are setters and getters for each of the properties. There is also a protected createWorkspace( String name ) method that subclasses can use to create their needed workspaces.

                          The createWorkspace( String name ) method works by first creating a JcrSessionFactory with the repository, default workspace, and system credentials. It calls jcrTemplate.setAllowCreate( !requireTransactionalSession ) to enforce the the transactional requirement (which I need in my app). I then call jcrTemplate.execute( new JcrCallback() {...}, true ); and in the callback create the new workspace. Since creating a workspace is implementation dependent, I may move this to a utility interface that can be implemented for each JCR package I work with, but right now I'm only using Jackrabbit so this isn't a priority for me. Actually, Costin, if you read this, that would be a useful hierarchy to have someplace in the SpringModule's JCR package, possibly an addition to JcrUtils()?

                          Class: JcrWorkspaceDao
                          Extends: JcrDaoSupport
                          Implements: <none>
                          Description:
                          This is my other abstract class. While AbstractJcrDao and its hierarchy is concerned with access to the entire repository, this hierarchy focuses on a single Workspace; most of the actual work takes place in this hierarchy. Currently it provides two functions: checkWorkspace() and logNodeTree( Node n ). The former method simply tries to create a new session by calling getJcrTemplate().execute( new JcrCallback() { ... }, true ); and simply logging the fact that the instance has been created for the particular workspace. The latter method simply walks a a Node hierarchy and logs the names of the nodes in the hierarchy; this is a useful tool for ensuring the workspace contains the node tree you think it does.


                          Class: Jcr<DataType>Dao
                          Extends: AbstractJcrDao
                          Implements: <DataType>Dao
                          Description:
                          In my system, I've got one workspace per user, with several types of data stored in each workspace; therefore, I have one class of this sort for each of those data types. The interface that it implements defines the action methods that can be called, much as you would expect for a database DAO; in fact, you should be able to replace the Jcr-based DAO with a JDBC-based DAO and the rest of your code won't notice because only your Spring dependency injection file had to change. This class implements those action methods (addSomething( ... ), findSomething( ... ), deleteSomething( ... ), etc.). Each of these action methods is delegated to a subclass of JcrWorkspaceDao which is created by the Jcr<DataType>WorkspaceDao getWorkspaceDao( String name ) method in this class.

                          Jcr<DataType>WorkspaceDao getWorkspaceDao( String name ) works by creating a JcrSessionFactory with the repository and credentials from the abstract superclass, and the workspace name given to it by the action method. I then create a JcrTemplate with the session factory, and call jcrTemplate.setAllowCreate( !isTransactionRequired() ) to ensure that I get transactional sessions when I need them (at runtime and in Integration testing, but not during Unit testing). With the JcrTemplate, I create a new Jcr<DataType>WorkspaceDao instance (the JcrTemplate is passed to the constructor). If the workspace specified by the session doesn't exist, the constructor throws a DataAccessResourceFailureException (from the org.springframework.dao package). I check the cause of the exception to ensure it really is a NoSuchWorkspaceException (from the javax.jcr package). If it is, I call the superclass createWorkspace() method for the workspace name. Assuming that succeeds, I try creating the new Jcr<DataType>WorkspaceDao instance again (this time I don't try to catch any exceptions). I then call the workspaceDao.initialize() method to create required or default Nodes in the new workspace.

                          Class: Jcr<DataType>WorkspaceDao
                          Extends: JcrWorkspaceDao
                          Implements: <none>
                          Description:

                          This is where the real work of this contraption is done. All the major interactions with the JCR Session objects take place here. The only constructor requires a JcrTemplate, which is passed to the superclass's setJcrTemplate() method (in JcrDaoSupport) before calling the superclass afterPropertiesSet() method (also in JcrDaoSupport). The purpose with these first two calls is to simulate the dependency injection workflow. I then call the checkWorkspace() method in the immediate superclass, JcrWorkspaceDao, to ensure the workspace has been created. If the workspace doesn't exist, the JcrSessionFactory will fail to create a session and throw an exception which is allowed to fall back to the caller to be processed as described above.

                          There's also an initialize() method to do initial setup in a newly created workspace for this type of data. All the other methods are action methods that actually add, delete, search, and edit Nodes in the workspace.

                          ---

                          So far, things are looking good. Workspaces get created on the fly as they are needed, and they are initialized. I'm having trouble with actually creating Nodes and setting properties in my action methods, but this seems to be an issue I'm having with Jackrabbit, not SpringModule's JCR package. Hopefully I'll get it worked out in the next day or two and be able to confirm that this setup actually does what its intended to do.

                          Comment


                          • #14
                            Nice answer!

                            Since creating a workspace is implementation dependent, I may move this to a utility interface that can be implemented for each JCR package I work with, but right now I'm only using Jackrabbit so this isn't a priority for me. Actually, Costin, if you read this, that would be a useful hierarchy to have someplace in the SpringModule's JCR package, possibly an addition to JcrUtils()?
                            I'm not sure I'm following you - creating a workspace is standardized - from the javadocs:
                            the Workspace object can be acquired by calling Session.getWorkspace() on the associated Session object.
                            .
                            Please post some code so I can get an idea about what you are need.

                            Comment


                            • #15
                              Creating a workspace

                              Hi Costin,

                              Getting the workspace from the session is standardized. However, making a new workspace is not. From the Jackrabbit FAQ:

                              How do I create new workspaces in Jackrabbit?
                              The JCR API does not contain features for creating or managing workspaces, so you need to use Jackrabbit-specific functionality for creating new workspaces.

                              You can create a new workspace either manually or programmatically. The manual way is to create a new workspace directory within the repository home directory and to place a new workspace.xml configuration file in that folder. You can use the configuration file of an existing workspace as an example, just remember to change the name of the workspace in the <Workspace name="...">" tag. See the Configuring Jackrabbit page for configuration details. Note also that you need to restart the repository instance to access the new workspace.

                              The programmatic way is to acquire a Workspace instance using the normal JCR API and to cast the instance to the Jackrabbit WorkspaceImpl class. You can then use the WorkspaceImpl.createWorkspace(String) method to create new workspaces.
                              Perhaps there are some implementations that automatically create a workspace when it doesn't exist, but since I've only dealt with Jackrabbit, I'm not aware of them.

                              Comment

                              Working...
                              X