eSoftHead
An excellent software outsourcing company

By Hai Nguyen Java Software Engineer Technology Tip Uncategorized (9) Comments



We know both Jackrabbit and Spring are awesome libraries. We always suggest our clients to use Jackrabbit when they want to store content in hierarchy structure, jackrabbit just do its tasks very well to hide the internal structure of content and we just work on its kind of nodes. We do not explain Spring benefits here since it is quite popular, and we can say we mainly use Spring to separate concerns of our services implementation and aspect programming for logging, caching, manage transaction. We used Jackrabbit and Spring many years and one year ago we move our content base solution from Jackrabbit 1 to Jackrabbit 2 and we need to revise our product code relate to Jackrabbit 2 to make it work nicely with Spring 3. This blog summarize what we did to make these two libraries work well.

First, we checkout spring jackrabbit integration on github https://github.com/jbellmann/jcr-springextension/tree/develop/se-jcr-jackrabbit. Since this library is not deployed in any public repository so we must download source codes and add it into our source repository. Then, we want to add our custom node types so I created new java class


MyCollabJcrSessionFactory2

and extend it to class


org.springframework.extensions.jcr.JcrSessionFactory

and I override method create registerNodeTypes

<em id="__mceDel">@Override
protected void registerNodeTypes() throws Exception {
    log.info("Register node types");
    final String[] jcrNamespaces = getSession().getWorkspace()

.getNamespaceRegistry().getPrefixes();

    boolean createNamespace = true;
    for (int i = 0; i < jcrNamespaces.length; i++) {
        if (jcrNamespaces[i].equals("mycollab")) {
            createNamespace = false;
            log.debug("Mycollab namespace exists.");
         }
    }

    if (createNamespace) {
        getSession()

.getNamespaceRegistry()

.registerNamespace("mycollab",

"http://www.esofthead.com/mycollab");

        log.debug("Successfully created Mycollab content namespace.");

    }

    if (getSession().getRootNode() == null) {
        throw new ContentException("Jcr session setup not successful.");
    }

    NodeTypeManager manager = (NodeTypeManager) getSession().getWorkspace()
.getNodeTypeManager();
    manager.registerNodeType(createMyCollabContentType(manager), true);
    manager.registerNodeType(createMyCollabFolderType(manager), true);
}

You can get the full source code of
MyCollabJcrSessionFactory2 at here https://github.com/haiphucnguyen/mycollab/blob/master/mycollab-services/src/main/java/com/esofthead/mycollab/module/ecm/MyCollabJcrSessionFactory2.java

then add it in spring context file


<bean id="repository"
    class="org.springframework.extensions.jcr.jackrabbit.JackrabbitRepositoryFactoryBean"
    p:configuration="classpath:/jackrabbit-repo.xml" p:homeDir="file:repo">
</bean>

<bean id="jcrSessionFactory"
    class="com.esofthead.mycollab.module.ecm.MyCollabJcrSessionFactory2">
    <property name="repository" ref="repository" />
    <property name="credentials">
        <bean class="javax.jcr.SimpleCredentials">
            <constructor-arg index="0" value="hainguyen" />
            <constructor-arg index="1" value="esofthead321" />
        </bean>
    </property>
</bean>

<bean id="jcrTemplate" class="org.springframework.extensions.jcr.JcrTemplate">
    <property name="sessionFactory" ref="jcrSessionFactory" />
    <property name="allowCreate" value="true" />
</bean>

And then you can get jcrTemplate object and use it in any spring service like this one

public class ContentJcrDaoImpl implements ContentJcrDao {

    private static Logger log = LoggerFactory.getLogger(ContentJcrDaoImpl.class);

    @Autowired
    private JcrTemplate jcrTemplate;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public void saveContent(final Content content, final String createdUser) {
        log.debug("Save content {} {}", content, jcrTemplate);

        jcrTemplate.execute(new JcrCallback() {
            @Override
            public Object doInJcr(Session session) throws IOException, RepositoryException {
                Node rootNode = session.getRootNode();
                Node node = getNode(rootNode, content.getPath());
                ...
            }
         });
    }
...
}

That it is :). If you have any questions or troubles in integration between Jackrabbit 2 and Spring 3, please post comments here and we are willing to help :)

zv7qrnb
FacebookTwitterGoogle+LinkedInGoogle BookmarksDZoneStumbleUponDeliciousInstapaperFlipboardShare

Comments (9)

  1. Maris Reply

    March 14, 2014 at 8:46 pm

    Is it possible to integrate with jackrabbits remote access via spring extensions?
    http://wiki.apache.org/jackrabbit/RemoteAccess

    • Hai Nguyen Reply

      March 15, 2014 at 6:03 am

      You can create your own RepositoryFactoryBean, by inheriting class org.springframework.extensions.jcr.RepositoryFactoryBean and override method protected abstract Repository createRepository() throws Exception. Below is the sample

      class RemoteRepositoryFactoryBean extends RepositoryFactoryBean {
      protected Repository createRepository() throws Exception {
      return JcrUtils.getRepository(“http://localhost:8080/server”);
      }

      }

      Hope that’s help.

  2. Yves Tanas Reply

    March 28, 2014 at 9:26 pm

    Any idea, on how i could use this with Spring Social ???

    • Hai Nguyen Reply

      March 28, 2014 at 9:28 pm

      Please describe your use case? and I can help if possible :)

  3. Yves Tanas Reply

    March 29, 2014 at 4:40 am

    I’d like to use Spring Social to login to Magnolia CMS, which uses a huge jackrabbit repository to store things.
    I even now know, where to find the Session and the Workspace inside java by using things like MgnlContext, but i don’t know how i could now dock onto this and make it possible in use with Spring Social.
    He is missing my dataSource.
    There are many Spring Social tutorials outside on using H2, Derby, MySql, i even use MySql with jackrabbit, but that doesn’t help me that much, as the data there is in a non readable format for me.
    So i thought i could look up something to bind to my Spring Social Sample, using the given jcr repository and workspaces, but as i have no feedbackpartner here, i don’t really know how that would work, what i try to do.
    Easiest way would be just to switch my repository, not ?
    Spring Social is not that heavy in the setup, but i can’t bind it to my jackrabbits repository and lookup the users workspace,.
    This sample here looks like it would be the best way to get into, what i try to do.

  4. Yves Tanas Reply

    March 29, 2014 at 4:43 am

    This is, what i did last:

    ${hibernate.dialect}
    ${hibernate.ejb.naming_strategy}
    ${hibernate.format_sql}
    ${hibernate.hbm2ddl.auto}
    ${hibernate.show_sql}

  5. Yves Tanas Reply

    March 29, 2014 at 7:58 am

    Oh that’s my question.
    i want to use it as javax.sql.DataSource, that would fit my needs

    • Hai Nguyen Reply

      March 29, 2014 at 4:28 pm

      I do not understand very well your question. It seems you would authenticate Jackrabbit with user account login to your system by using Spring Social. It depends on how you organize your content, you can add the authentication and authorization on the top of jackrabbit and not use its JAAS module. If the question you want to use datasource in jackrabbit, here is the code could be useful for you:

      public class BundleDbPersistenceManagerExt extends BundleDbPersistenceManager {

      /**
      * {@inheritDoc}
      */
      public void init(PMContext context) throws Exception {
      setDriver(“javax.naming.InitialContext”);
      setUrl(“java:comp/env/jdbc/mycollabdatasource”);

      if (getSchemaObjectPrefix() == null) {
      setSchemaObjectPrefix(“ecm_p_workspace”);
      }

      if (getDatabaseType() == null) {
      setDatabaseType(“mysql”);
      }
      super.init(context);
      }
      }

      and in jackrabbit configuration file, you can define PersistenceManager as it

      To use datasource in jackrabbit, you just use driverClass is “javax.naming.InitialContext” and url is name of your datasource.
      Hope it is help :)

  6. upendra Reply

    May 15, 2014 at 1:59 pm

    Hi,
    i am new to this jackrabbit , i am looking for upload and read the pdf files and provide access control, please provide any sample example.

    thanks in advance.

Leave a Comment

Read previous post:
How to embed Jetty servlet container in your application

In one of our big Java projects names MyCollab, we deal with a challenge of control the whole life cycle...

How to force Maven use Java 7 to build java projects on MacOS

We developed an enterprise complex project using Maven on various OSes as Windows, Linux and MacOS. From now, we decided...

Close