X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fkernel%2FJackrabbitNode.java;h=8ef16c44ffc6d88a68ce261cd90e4176e6830ae5;hb=92ac99f3ededbcd28def2bf9601bb33c02a351b3;hp=e36f713563d384601519060c83287819c1040be8;hpb=63446804f4954bfedd50d8c692bde0fab13aa1ec;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/JackrabbitNode.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/JackrabbitNode.java index e36f71356..8ef16c44f 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/JackrabbitNode.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/JackrabbitNode.java @@ -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,39 +10,55 @@ 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; import org.apache.commons.logging.LogFactory; +import org.apache.jackrabbit.core.RepositoryContext; import org.apache.jackrabbit.core.RepositoryImpl; +import org.apache.jackrabbit.core.cache.CacheManager; import org.apache.jackrabbit.core.config.RepositoryConfig; import org.apache.jackrabbit.core.config.RepositoryConfigurationParser; +import org.apache.jackrabbit.stats.RepositoryStatisticsImpl; import org.argeo.ArgeoException; +import org.argeo.cms.CmsException; import org.argeo.jackrabbit.JackrabbitWrapper; import org.argeo.jcr.ArgeoJcrConstants; +import org.argeo.jcr.DefaultRepositoryRegister; 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 RepositoryContext repositoryContext; + private ServiceRegistration repositoryReg; public JackrabbitNode(BundleContext bundleContext) { setBundleContext(bundleContext); - createNode(); - setCndFiles(Arrays.asList(KernelConstants.DEFAULT_CNDS)); - prepareDataModel(); + JackrabbitNodeType type = JackrabbitNodeType.valueOf(prop(REPO_TYPE, + h2.name())); + try { + repositoryContext = 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() { + void publish(DefaultRepositoryRegister repositoryRegister) { Hashtable regProps = new Hashtable(); - regProps.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, - ArgeoJcrConstants.ALIAS_NODE); + regProps.put(JCR_REPOSITORY_ALIAS, ALIAS_NODE); repositoryReg = getBundleContext().registerService(Repository.class, this, regProps); + repositoryRegister.register(this, regProps); } public void destroy() { @@ -48,86 +66,135 @@ class JackrabbitNode extends JackrabbitWrapper { ((RepositoryImpl) getRepository()).shutdown(); } - Dictionary getDefaults() { - return KernelUtils.asDictionary(getClass().getClassLoader(), - "/org/argeo/cms/internal/kernel/jackrabbit-node.properties"); + RepositoryStatisticsImpl getRepositoryStatistics() { + return repositoryContext.getRepositoryStatistics(); } - InputSource getConfigurationXml(JackrabbitNodeTypes type) { + private RepositoryConfig getConfiguration(JackrabbitNodeType type, + Hashtable 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 getConfigurationProperties( + JackrabbitNodeType type) { + // use Hashtable to ease integration with Properties + Hashtable defaults = new Hashtable(); - File osgiInstanceDir = KernelUtils - .getOsgiInstanceDir(getBundleContext()); + // home + File osgiInstanceDir = KernelUtils.getOsgiInstanceDir(); 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); + // common + setProp(defaults, REPO_DEFAULT_WORKSPACE, "main"); + setProp(defaults, REPO_MAX_POOL_SIZE, "10"); + // Jackrabbit defaults + setProp(defaults, REPO_BUNDLE_CACHE_MB, "8"); + // See http://wiki.apache.org/jackrabbit/Search + setProp(defaults, REPO_EXTRACTOR_POOL_SIZE, "0"); + setProp(defaults, REPO_SEARCH_CACHE_SIZE, "1000"); + setProp(defaults, REPO_MAX_VOLATILE_INDEX_SIZE, "1048576"); + + // 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; + } - // jackrabbitContainer.init(); + private void setProp(Dictionary props, String key, + String defaultValue) { + String value = prop(key, defaultValue); + props.put(key, value); + } + + private String prop(String key, String defaultValue) { + // TODO use OSGi CM instead of Framework/System properties + return KernelUtils.getFrameworkProp(key, defaultValue); + } - RepositoryImpl repository = createJackrabbitRepository( - configurationProperties, getConfigurationXml(null)); + private RepositoryContext createNode(JackrabbitNodeType type) + throws RepositoryException { + Hashtable vars = getConfigurationProperties(type); + RepositoryConfig repositoryConfig = getConfiguration(type, vars); + RepositoryContext repositoryContext = createJackrabbitRepository(repositoryConfig); + RepositoryImpl repository = repositoryContext.getRepository(); + + // cache + String maxCacheMbStr = prop(REPO_MAX_CACHE_MB, null); + if (maxCacheMbStr != null) { + Integer maxCacheMB = Integer.parseInt(maxCacheMbStr); + CacheManager cacheManager = repository.getCacheManager(); + cacheManager.setMaxMemory(maxCacheMB * 1024l * 1024l); + cacheManager.setMaxMemoryPerCache((maxCacheMB / 4) * 1024l * 1024l); + } + // wrap the repository setRepository(repository); + return repositoryContext; } - private RepositoryImpl createJackrabbitRepository(Properties vars, - InputSource config) { + private RepositoryContext 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); - - 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); - } + // + // Actual repository creation + // + RepositoryContext repositoryContext = RepositoryContext + .create(repositoryConfig); + + double duration = ((double) (System.currentTimeMillis() - begin)) / 1000; + if (log.isTraceEnabled()) + log.trace("Created Jackrabbit repository in " + duration + + " s, home: " + homeDirectory); + + return repositoryContext; } - }