JCR query editor
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 22 Jan 2011 19:05:43 +0000 (19:05 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 22 Jan 2011 19:05:43 +0000 (19:05 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@4067 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

13 files changed:
eclipse/plugins/org.argeo.eclipse.ui.jcr/.classpath [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/.project [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/build.properties [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/pom.xml [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/OpenGenericJcrQueryEditor.java [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/AbstractJcrQueryEditor.java [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/GenericJcrQueryEditor.java [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/JcrQueryEditorInput.java [new file with mode: 0644]
eclipse/plugins/org.argeo.eclipse.ui/pom.xml
eclipse/plugins/pom.xml
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/server/jackrabbit/JackrabbitContainer.java

diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/.classpath b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.classpath
new file mode 100644 (file)
index 0000000..92f19d2
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src/main/java"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/.project b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.project
new file mode 100644 (file)
index 0000000..d152683
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.eclipse.ui.jcr</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.jdt.core.prefs b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..57d3f00
--- /dev/null
@@ -0,0 +1,8 @@
+#Sat Jan 22 14:25:47 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.pde.core.prefs b/eclipse/plugins/org.argeo.eclipse.ui.jcr/.settings/org.eclipse.pde.core.prefs
new file mode 100644 (file)
index 0000000..81635e9
--- /dev/null
@@ -0,0 +1,4 @@
+#Sat Jan 22 14:25:47 CET 2011
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/build.properties b/eclipse/plugins/org.argeo.eclipse.ui.jcr/build.properties
new file mode 100644 (file)
index 0000000..5fc538b
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/main/java/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/pom.xml b/eclipse/plugins/org.argeo.eclipse.ui.jcr/pom.xml
new file mode 100644 (file)
index 0000000..4f041ee
--- /dev/null
@@ -0,0 +1,80 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.argeo.commons.eclipse</groupId>
+               <version>0.2.2-SNAPSHOT</version>
+               <artifactId>plugins</artifactId>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.eclipse.ui.jcr</artifactId>
+       <name>Commons Eclipse UI JCR</name>
+       <packaging>jar</packaging>
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-source-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.felix</groupId>
+                               <artifactId>maven-bundle-plugin</artifactId>
+                               <version>${version.maven-bundle-plugin}</version>
+                               <configuration>
+                                       <instructions>
+                                               <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>
+                                               <Import-Package>
+                                                       org.eclipse.swt,
+                                                       *
+                                               </Import-Package>
+                                       </instructions>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+       <dependencies>
+
+               <!-- Argeo Eclipse distribution (common dependencies for both RAP and RCP) -->
+               <dependency>
+                       <groupId>org.argeo.commons.eclipse</groupId>
+                       <artifactId>org.argeo.eclipse.dep.common</artifactId>
+                       <version>0.2.2-SNAPSHOT</version>
+               </dependency>
+
+               <!-- JCR -->
+               <dependency>
+                       <groupId>org.argeo.dep.osgi</groupId>
+                       <artifactId>org.argeo.dep.osgi.jcr</artifactId>
+               </dependency>
+
+               <!-- RCP only dependency, needed at compile time -->
+               <dependency>
+                       <groupId>org.argeo.commons.eclipse</groupId>
+                       <artifactId>org.argeo.eclipse.dep.rcp</artifactId>
+                       <version>${version.argeo-commons}</version>
+                       <scope>provided</scope>
+               </dependency>
+
+               <!-- Commons -->
+               <dependency>
+                       <groupId>org.argeo.commons.basic</groupId>
+                       <artifactId>org.argeo.basic.nodeps</artifactId>
+                       <version>0.2.2-SNAPSHOT</version>
+               </dependency>
+
+               <!-- Others -->
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
+               </dependency>
+
+       </dependencies>
+</project>
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/OpenGenericJcrQueryEditor.java b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/commands/OpenGenericJcrQueryEditor.java
new file mode 100644 (file)
index 0000000..1169747
--- /dev/null
@@ -0,0 +1,30 @@
+package org.argeo.eclipse.ui.jcr.commands;
+
+import org.argeo.eclipse.ui.jcr.editors.JcrQueryEditorInput;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/** Open a JCR query editor. */
+public class OpenGenericJcrQueryEditor extends AbstractHandler {
+       private String editorId;
+
+       public Object execute(ExecutionEvent event) throws ExecutionException {
+               try {
+                       JcrQueryEditorInput editorInput = new JcrQueryEditorInput("", null);
+                       IWorkbenchPage activePage = HandlerUtil.getActiveWorkbenchWindow(
+                                       event).getActivePage();
+                       activePage.openEditor(editorInput, editorId);
+               } catch (Exception e) {
+                       throw new ExecutionException("Cannot open editor", e);
+               }
+               return null;
+       }
+
+       public void setEditorId(String editorId) {
+               this.editorId = editorId;
+       }
+
+}
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/AbstractJcrQueryEditor.java b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/AbstractJcrQueryEditor.java
new file mode 100644 (file)
index 0000000..802fc0f
--- /dev/null
@@ -0,0 +1,201 @@
+package org.argeo.eclipse.ui.jcr.editors;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.QueryResult;
+import javax.jcr.query.Row;
+import javax.jcr.query.RowIterator;
+
+import org.argeo.ArgeoException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorPart;
+
+/** Executes any JCR query. */
+public abstract class AbstractJcrQueryEditor extends EditorPart {
+       protected String initialQuery;
+       protected String initialQueryType;
+
+       private Session session;
+
+       private TableViewer viewer;
+       private List<TableViewerColumn> tableViewerColumns = new ArrayList<TableViewerColumn>();
+
+       protected abstract void createQueryForm(Composite parent);
+
+       @Override
+       public void init(IEditorSite site, IEditorInput input)
+                       throws PartInitException {
+               JcrQueryEditorInput editorInput = (JcrQueryEditorInput) input;
+               initialQuery = editorInput.getQuery();
+               initialQueryType = editorInput.getQueryType();
+               setSite(site);
+               setInput(editorInput);
+       }
+
+       @Override
+       public final void createPartControl(final Composite parent) {
+               parent.setLayout(new FillLayout());
+
+               SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
+               sashForm.setSashWidth(2);
+               sashForm.setLayout(new FillLayout());
+
+               Composite top = new Composite(sashForm, SWT.NONE);
+               top.setLayout(new GridLayout(1, false));
+               // Device device = Display.getCurrent();
+               // Color red = new Color(device, 255, 0, 0);
+               // top.setBackground(red);
+               createQueryForm(top);
+
+               Composite bottom = new Composite(sashForm, SWT.NONE);
+               bottom.setLayout(new GridLayout(1, false));
+               sashForm.setWeights(new int[] { 30, 70 });
+
+               viewer = new TableViewer(bottom);
+               viewer.getTable().setLayoutData(
+                               new GridData(SWT.FILL, SWT.FILL, true, true));
+               viewer.getTable().setHeaderVisible(true);
+               viewer.setContentProvider(new QueryResultContentProvider());
+               // viewer.setLabelProvider(new QueryResultLabelProvider());
+               viewer.setInput(getEditorSite());
+       }
+
+       protected void executeQuery(String statement) {
+               try {
+                       QueryResult qr = session.getWorkspace().getQueryManager()
+                                       .createQuery(statement, initialQueryType).execute();
+
+                       // remove previous columns
+                       for (TableViewerColumn tvc : tableViewerColumns)
+                               tvc.getColumn().dispose();
+
+                       for (final String columnName : qr.getColumnNames()) {
+                               TableViewerColumn tvc = new TableViewerColumn(viewer, SWT.NONE);
+                               tvc.getColumn().setWidth(50);
+                               tvc.getColumn().setText(columnName);
+                               tvc.setLabelProvider(new ColumnLabelProvider() {
+
+                                       public String getText(Object element) {
+                                               Row row = (Row) element;
+                                               try {
+                                                       return row.getValue(columnName).getString();
+                                               } catch (RepositoryException e) {
+                                                       throw new ArgeoException("Cannot display row "
+                                                                       + row, e);
+                                               }
+                                       }
+
+                                       public Image getImage(Object element) {
+                                               return null;
+                                       }
+                               });
+                               tableViewerColumns.add(tvc);
+                       }
+
+                       viewer.setInput(qr);
+               } catch (RepositoryException e) {
+                       ErrorDialog.openError(null, "Error", "Cannot execute JCR query: "
+                                       + statement, new Status(IStatus.ERROR,
+                                       "org.argeo.eclipse.ui.jcr", e.getMessage()));
+                       // throw new ArgeoException("Cannot execute JCR query " + statement,
+                       // e);
+               }
+       }
+
+       private class QueryResultContentProvider implements
+                       IStructuredContentProvider {
+
+               public void dispose() {
+               }
+
+               public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               }
+
+               public Object[] getElements(Object inputElement) {
+                       if (!(inputElement instanceof QueryResult))
+                               return new String[] {};
+
+                       try {
+                               QueryResult queryResult = (QueryResult) inputElement;
+                               List<Row> rows = new ArrayList<Row>();
+                               RowIterator rit = queryResult.getRows();
+                               while (rit.hasNext()) {
+                                       rows.add(rit.nextRow());
+                               }
+
+                               // List<Node> elems = new ArrayList<Node>();
+                               // NodeIterator nit = queryResult.getNodes();
+                               // while (nit.hasNext()) {
+                               // elems.add(nit.nextNode());
+                               // }
+                               return rows.toArray();
+                       } catch (RepositoryException e) {
+                               throw new ArgeoException("Cannot read query result", e);
+                       }
+               }
+
+       }
+
+       // private class QueryResultLabelProvider extends LabelProvider implements
+       // ITableLabelProvider {
+       // public String getColumnText(Object element, int columnIndex) {
+       // Row row = (Row) element;
+       // try {
+       // return row.getValues()[columnIndex].toString();
+       // } catch (RepositoryException e) {
+       // throw new ArgeoException("Cannot display row " + row, e);
+       // }
+       // }
+       //
+       // public Image getColumnImage(Object element, int columnIndex) {
+       // return null;
+       // }
+       //
+       // }
+
+       @Override
+       public boolean isDirty() {
+               return false;
+       }
+
+       @Override
+       public void doSave(IProgressMonitor monitor) {
+               // TODO save the query in JCR?
+
+       }
+
+       @Override
+       public void doSaveAs() {
+       }
+
+       @Override
+       public boolean isSaveAsAllowed() {
+               return false;
+       }
+
+       public void setSession(Session session) {
+               this.session = session;
+       }
+
+}
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/GenericJcrQueryEditor.java b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/GenericJcrQueryEditor.java
new file mode 100644 (file)
index 0000000..a02268b
--- /dev/null
@@ -0,0 +1,41 @@
+package org.argeo.eclipse.ui.jcr.editors;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+
+/** Executes any JCR query. */
+public class GenericJcrQueryEditor extends AbstractJcrQueryEditor {
+       private Text queryField;
+
+       @Override
+       public void createQueryForm(Composite parent) {
+               parent.setLayout(new GridLayout(1, false));
+
+               queryField = new Text(parent, SWT.BORDER | SWT.MULTI | SWT.WRAP);
+               queryField.setText(initialQuery);
+               queryField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+               Button execute = new Button(parent, SWT.PUSH);
+               execute.setText("Execute");
+
+               Listener executeListener = new Listener() {
+                       public void handleEvent(Event event) {
+                               executeQuery(queryField.getText());
+                       }
+               };
+
+               execute.addListener(SWT.Selection, executeListener);
+               // queryField.addListener(SWT.DefaultSelection, executeListener);
+       }
+
+       @Override
+       public void setFocus() {
+               queryField.setFocus();
+       }
+}
diff --git a/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/JcrQueryEditorInput.java b/eclipse/plugins/org.argeo.eclipse.ui.jcr/src/main/java/org/argeo/eclipse/ui/jcr/editors/JcrQueryEditorInput.java
new file mode 100644 (file)
index 0000000..45c2a68
--- /dev/null
@@ -0,0 +1,53 @@
+package org.argeo.eclipse.ui.jcr.editors;
+
+import javax.jcr.query.Query;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPersistableElement;
+
+public class JcrQueryEditorInput implements IEditorInput {
+       private final String query;
+       private final String queryType;
+
+       public JcrQueryEditorInput(String query, String queryType) {
+               this.query = query;
+               if (queryType == null)
+                       this.queryType = Query.JCR_SQL2;
+               else
+                       this.queryType = queryType;
+       }
+
+       public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
+               return null;
+       }
+
+       public boolean exists() {
+               return true;
+       }
+
+       public ImageDescriptor getImageDescriptor() {
+               return null;
+       }
+
+       public String getName() {
+               return query;
+       }
+
+       public IPersistableElement getPersistable() {
+               return null;
+       }
+
+       public String getToolTipText() {
+               return query;
+       }
+
+       public String getQuery() {
+               return query;
+       }
+
+       public String getQueryType() {
+               return queryType;
+       }
+
+}
index ee53982525df00e1ed6305a0f6b976dfe053c99b..e4adbdcd21580055e16545020bb98f6b5383e2a3 100644 (file)
                        <version>0.2.2-SNAPSHOT</version>
                </dependency>
 
+               <!-- JCR -->
+               <dependency>
+                       <groupId>org.argeo.dep.osgi</groupId>
+                       <artifactId>org.argeo.dep.osgi.jcr</artifactId>
+               </dependency>
+
                <!-- RCP only dependency, needed at compile time -->
                <dependency>
-                       <groupId>org.eclipse.ui</groupId>
-                       <artifactId>org.eclipse.ui</artifactId>
+                       <groupId>org.argeo.commons.eclipse</groupId>
+                       <artifactId>org.argeo.eclipse.dep.rcp</artifactId>
+                       <version>${version.argeo-commons}</version>
                        <scope>provided</scope>
                </dependency>
 
index 98f6bcb253166ec46d8ba669faed03984e8a1e3b..f8facd6f44f51682639229cef9fdddbbd2495749 100644 (file)
@@ -12,6 +12,7 @@
        <packaging>pom</packaging>
        <modules>
                <module>org.argeo.eclipse.ui</module>
+               <module>org.argeo.eclipse.ui.jcr</module>
        </modules>
        <build>
                <resources>
index f06163f34cfaaccc878cb4ecda9fbea3bca14fab..979788940c01c7f5afe06d5e49fef792ed2673d6 100644 (file)
 
 package org.argeo.server.jackrabbit;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.jcr.Credentials;
@@ -34,20 +38,23 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.commons.NamespaceHelper;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.TransientRepository;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
 import org.argeo.ArgeoException;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ResourceLoaderAware;
 import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
 
 /**
  * Wrapper around a Jackrabbit repository which allows to configure it in Spring
  * and expose it as a {@link Repository}.
  */
 public class JackrabbitContainer implements InitializingBean, DisposableBean,
-               Repository {
+               Repository, ResourceLoaderAware {
        private Log log = LogFactory.getLog(JackrabbitContainer.class);
 
        private Resource configuration;
@@ -57,10 +64,24 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
 
        private Repository repository;
 
+       private ResourceLoader resourceLoader;
+
+       /** Node type definitions in CND format */
+       private List<byte[]> cnds = new ArrayList<byte[]>();
+       private List<String> cndFiles = new ArrayList<String>();
+
        /** Namespaces to register: key is prefix, value namespace */
        private Map<String, String> namespaces = new HashMap<String, String>();
 
        public void afterPropertiesSet() throws Exception {
+               // Load cnds as resources
+               for (String resUrl : cndFiles) {
+
+                       Resource res = resourceLoader.getResource(resUrl);
+                       byte[] arr = IOUtils.toByteArray(res.getInputStream());
+                       cnds.add(arr);
+               }
+
                if (inMemory && homeDirectory.exists()) {
                        FileUtils.deleteDirectory(homeDirectory);
                        log.warn("Deleted Jackrabbit home directory " + homeDirectory);
@@ -146,11 +167,19 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                try {
                        NamespaceHelper namespaceHelper = new NamespaceHelper(session);
                        namespaceHelper.registerNamespaces(namespaces);
-               } catch (RepositoryException e) {
+
+                       for (byte[] arr : cnds)
+                               CndImporter.registerNodeTypes(new InputStreamReader(
+                                               new ByteArrayInputStream(arr)), session);
+               } catch (Exception e) {
                        throw new ArgeoException("Cannot process new session", e);
                }
        }
 
+       public void setResourceLoader(ResourceLoader resourceLoader) {
+               this.resourceLoader = resourceLoader;
+       }
+
        public boolean isStandardDescriptor(String key) {
                return repository.isStandardDescriptor(key);
        }
@@ -184,4 +213,8 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                this.namespaces = namespaces;
        }
 
+       public void setCndFiles(List<String> cndFiles) {
+               this.cndFiles = cndFiles;
+       }
+
 }