Make Jackrabbit node type configurable
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / JackrabbitNode.java
index e36f713563d384601519060c83287819c1040be8..3bda38813b79b3ce69c6e590b459f389ec05547e 100644 (file)
@@ -1,5 +1,7 @@
 package org.argeo.cms.internal.kernel;
 
+import static org.argeo.cms.internal.kernel.JackrabbitNodeType.h2;
+
 import java.io.File;
 import java.io.InputStream;
 import java.util.Arrays;
@@ -8,6 +10,7 @@ import java.util.Hashtable;
 import java.util.Properties;
 
 import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
@@ -16,29 +19,38 @@ import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
 import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
 import org.argeo.ArgeoException;
+import org.argeo.cms.CmsException;
 import org.argeo.jackrabbit.JackrabbitWrapper;
 import org.argeo.jcr.ArgeoJcrConstants;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 import org.xml.sax.InputSource;
 
-/** Data storage */
-class JackrabbitNode extends JackrabbitWrapper {
+/** Jacrabbit based data layer */
+class JackrabbitNode extends JackrabbitWrapper implements KernelConstants,
+               ArgeoJcrConstants {
        private static Log log = LogFactory.getLog(JackrabbitNode.class);
 
        private ServiceRegistration<Repository> repositoryReg;
 
        public JackrabbitNode(BundleContext bundleContext) {
                setBundleContext(bundleContext);
-               createNode();
-               setCndFiles(Arrays.asList(KernelConstants.DEFAULT_CNDS));
-               prepareDataModel();
+               // TODO with OSGi CM
+               JackrabbitNodeType type = JackrabbitNodeType.valueOf(System
+                               .getProperty(REPO_TYPE, h2.name()));
+               try {
+                       createNode(type);
+                       setCndFiles(Arrays.asList(DEFAULT_CNDS));
+                       prepareDataModel();
+               } catch (Exception e) {
+                       throw new ArgeoException(
+                                       "Cannot create Jackrabbit repository of type " + type, e);
+               }
        }
 
        public void publish() {
                Hashtable<String, String> regProps = new Hashtable<String, String>();
-               regProps.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS,
-                               ArgeoJcrConstants.ALIAS_NODE);
+               regProps.put(JCR_REPOSITORY_ALIAS, ALIAS_NODE);
                repositoryReg = getBundleContext().registerService(Repository.class,
                                this, regProps);
        }
@@ -53,81 +65,108 @@ class JackrabbitNode extends JackrabbitWrapper {
                                "/org/argeo/cms/internal/kernel/jackrabbit-node.properties");
        }
 
-       InputSource getConfigurationXml(JackrabbitNodeTypes type) {
+       private RepositoryConfig getConfiguration(JackrabbitNodeType type,
+                       Hashtable<String, Object> vars) throws RepositoryException {
                ClassLoader cl = getClass().getClassLoader();
-               InputStream in = cl
-                               .getResourceAsStream("/org/argeo/cms/internal/kernel/repository-h2.xml");
-               return new InputSource(in);
-       }
-
-       Properties getDefaultConfigurationProperties() {
-               Properties configurationProperties = new Properties();
-               configurationProperties.setProperty(KernelConstants.REPO_DBUSER, "sa");
-               configurationProperties
-                               .setProperty(KernelConstants.REPO_DBPASSWORD, "");
-               configurationProperties.setProperty(KernelConstants.REPO_MAX_POOL_SIZE,
-                               "10");
-               configurationProperties.setProperty(
-                               KernelConstants.REPO_DEFAULT_WORKSPACE, "main");
-               return configurationProperties;
+               InputStream in = null;
+               try {
+                       final String base = "/org/argeo/cms/internal/kernel";
+                       switch (type) {
+                       case h2:
+                               in = cl.getResourceAsStream(base + "/repository-h2.xml");
+                               break;
+                       case postgresql:
+                               in = cl.getResourceAsStream(base + "/repository-postgresql.xml");
+                               break;
+                       case memory:
+                               in = cl.getResourceAsStream(base + "/repository-memory.xml");
+                               break;
+                       default:
+                               throw new CmsException("Unsupported node type " + type);
+                       }
+
+                       if (in == null)
+                               throw new CmsException("Repository configuration not found");
+                       InputSource config = new InputSource(in);
+                       Properties jackrabbitProps = new Properties();
+                       jackrabbitProps.putAll(vars);
+                       RepositoryConfig repositoryConfig = RepositoryConfig.create(config,
+                                       jackrabbitProps);
+                       return repositoryConfig;
+               } finally {
+                       IOUtils.closeQuietly(in);
+               }
        }
 
-       private void createNode() {
-               Thread.currentThread().setContextClassLoader(
-                               getClass().getClassLoader());
+       private Hashtable<String, Object> getConfigurationProperties(
+                       JackrabbitNodeType type) {
+               // use Hashtable to ease integration with Properties
+               Hashtable<String, Object> defaults = new Hashtable<String, Object>();
 
+               // home
                File osgiInstanceDir = KernelUtils
                                .getOsgiInstanceDir(getBundleContext());
                File homeDir = new File(osgiInstanceDir, "node");
-
-               // H2
-               String dburl = "jdbc:h2:" + homeDir.getPath() + "/h2/repository";
-               Properties configurationProperties = getDefaultConfigurationProperties();
-               configurationProperties.setProperty(KernelConstants.REPO_DBURL, dburl);
-               configurationProperties.put(
-                               RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
+               // home cannot be overridden
+               defaults.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
                                homeDir.getAbsolutePath());
-               // InputSource configurationXml = getConfigurationXml(null);
 
-               // jackrabbitContainer.setHomeDirectory(homeDir);
-               // jackrabbitContainer.setConfigurationProperties(configurationProperties);
-               // jackrabbitContainer.setConfigurationXml(configurationXml);
-
-               // jackrabbitContainer.init();
+               // common
+               setProp(defaults, REPO_DEFAULT_WORKSPACE, "main");
+               setProp(defaults, REPO_MAX_POOL_SIZE, "10");
+
+               // specific
+               String dburl;
+               switch (type) {
+               case h2:
+                       dburl = "jdbc:h2:" + homeDir.getPath() + "/h2/repository";
+                       setProp(defaults, REPO_DBURL, dburl);
+                       setProp(defaults, REPO_DBUSER, "sa");
+                       setProp(defaults, REPO_DBPASSWORD, "");
+                       break;
+               case postgresql:
+                       dburl = "jdbc:postgresql://localhost/demo";
+                       setProp(defaults, REPO_DBURL, dburl);
+                       setProp(defaults, REPO_DBUSER, "argeo");
+                       setProp(defaults, REPO_DBPASSWORD, "argeo");
+                       break;
+               case memory:
+                       break;
+               default:
+                       throw new CmsException("Unsupported node type " + type);
+               }
+               return defaults;
+       }
 
-               RepositoryImpl repository = createJackrabbitRepository(
-                               configurationProperties, getConfigurationXml(null));
+       private void setProp(Dictionary<String, Object> props, String key,
+                       String defaultValue) {
+               // TODO use OSGi CM instead of System properties
+               String value = System.getProperty(key, defaultValue);
+               props.put(key, value);
+       }
 
+       private void createNode(JackrabbitNodeType type) throws RepositoryException {
+               Hashtable<String, Object> vars = getConfigurationProperties(type);
+               RepositoryConfig repositoryConfig = getConfiguration(type, vars);
+               RepositoryImpl repository = createJackrabbitRepository(repositoryConfig);
                setRepository(repository);
        }
 
-       private RepositoryImpl createJackrabbitRepository(Properties vars,
-                       InputSource config) {
+       private RepositoryImpl createJackrabbitRepository(
+                       RepositoryConfig repositoryConfig) throws RepositoryException {
                File homeDirectory = null;
                long begin = System.currentTimeMillis();
-               InputStream configurationIn = null;
                RepositoryImpl repository;
-               try {
-                       RepositoryConfig repositoryConfig = RepositoryConfig.create(config,
-                                       vars);
+               //
+               // Actual repository creation
+               //
+               repository = RepositoryImpl.create(repositoryConfig);
 
-                       //
-                       // Actual repository creation
-                       //
-                       repository = RepositoryImpl.create(repositoryConfig);
+               double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+               if (log.isTraceEnabled())
+                       log.trace("Created Jackrabbit repository in " + duration
+                                       + " s, home: " + homeDirectory);
 
-                       double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
-                       if (log.isTraceEnabled())
-                               log.trace("Created Jackrabbit repository in " + duration
-                                               + " s, home: " + homeDirectory);
-
-                       return repository;
-               } catch (Exception e) {
-                       throw new ArgeoException("Cannot create Jackrabbit repository "
-                                       + homeDirectory, e);
-               } finally {
-                       IOUtils.closeQuietly(configurationIn);
-               }
+               return repository;
        }
-
 }