]> git.argeo.org Git - lgpl/argeo-commons.git/blob - JackrabbitNode.java
8ef16c44ffc6d88a68ce261cd90e4176e6830ae5
[lgpl/argeo-commons.git] / JackrabbitNode.java
1 package org.argeo.cms.internal.kernel;
2
3 import static org.argeo.cms.internal.kernel.JackrabbitNodeType.h2;
4
5 import java.io.File;
6 import java.io.InputStream;
7 import java.util.Arrays;
8 import java.util.Dictionary;
9 import java.util.Hashtable;
10 import java.util.Properties;
11
12 import javax.jcr.Repository;
13 import javax.jcr.RepositoryException;
14
15 import org.apache.commons.io.IOUtils;
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.apache.jackrabbit.core.RepositoryContext;
19 import org.apache.jackrabbit.core.RepositoryImpl;
20 import org.apache.jackrabbit.core.cache.CacheManager;
21 import org.apache.jackrabbit.core.config.RepositoryConfig;
22 import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
23 import org.apache.jackrabbit.stats.RepositoryStatisticsImpl;
24 import org.argeo.ArgeoException;
25 import org.argeo.cms.CmsException;
26 import org.argeo.jackrabbit.JackrabbitWrapper;
27 import org.argeo.jcr.ArgeoJcrConstants;
28 import org.argeo.jcr.DefaultRepositoryRegister;
29 import org.osgi.framework.BundleContext;
30 import org.osgi.framework.ServiceRegistration;
31 import org.xml.sax.InputSource;
32
33 /** Jacrabbit based data layer */
34 class JackrabbitNode extends JackrabbitWrapper implements KernelConstants,
35 ArgeoJcrConstants {
36 private static Log log = LogFactory.getLog(JackrabbitNode.class);
37
38 private RepositoryContext repositoryContext;
39
40 private ServiceRegistration<Repository> repositoryReg;
41
42 public JackrabbitNode(BundleContext bundleContext) {
43 setBundleContext(bundleContext);
44 JackrabbitNodeType type = JackrabbitNodeType.valueOf(prop(REPO_TYPE,
45 h2.name()));
46 try {
47 repositoryContext = createNode(type);
48 setCndFiles(Arrays.asList(DEFAULT_CNDS));
49 prepareDataModel();
50 } catch (Exception e) {
51 throw new ArgeoException(
52 "Cannot create Jackrabbit repository of type " + type, e);
53 }
54 }
55
56 void publish(DefaultRepositoryRegister repositoryRegister) {
57 Hashtable<String, String> regProps = new Hashtable<String, String>();
58 regProps.put(JCR_REPOSITORY_ALIAS, ALIAS_NODE);
59 repositoryReg = getBundleContext().registerService(Repository.class,
60 this, regProps);
61 repositoryRegister.register(this, regProps);
62 }
63
64 public void destroy() {
65 repositoryReg.unregister();
66 ((RepositoryImpl) getRepository()).shutdown();
67 }
68
69 RepositoryStatisticsImpl getRepositoryStatistics() {
70 return repositoryContext.getRepositoryStatistics();
71 }
72
73 private RepositoryConfig getConfiguration(JackrabbitNodeType type,
74 Hashtable<String, Object> vars) throws RepositoryException {
75 ClassLoader cl = getClass().getClassLoader();
76 InputStream in = null;
77 try {
78 final String base = "/org/argeo/cms/internal/kernel";
79 switch (type) {
80 case h2:
81 in = cl.getResourceAsStream(base + "/repository-h2.xml");
82 break;
83 case postgresql:
84 in = cl.getResourceAsStream(base + "/repository-postgresql.xml");
85 break;
86 case memory:
87 in = cl.getResourceAsStream(base + "/repository-memory.xml");
88 break;
89 default:
90 throw new CmsException("Unsupported node type " + type);
91 }
92
93 if (in == null)
94 throw new CmsException("Repository configuration not found");
95 InputSource config = new InputSource(in);
96 Properties jackrabbitProps = new Properties();
97 jackrabbitProps.putAll(vars);
98 RepositoryConfig repositoryConfig = RepositoryConfig.create(config,
99 jackrabbitProps);
100 return repositoryConfig;
101 } finally {
102 IOUtils.closeQuietly(in);
103 }
104 }
105
106 private Hashtable<String, Object> getConfigurationProperties(
107 JackrabbitNodeType type) {
108 // use Hashtable to ease integration with Properties
109 Hashtable<String, Object> defaults = new Hashtable<String, Object>();
110
111 // home
112 File osgiInstanceDir = KernelUtils.getOsgiInstanceDir();
113 File homeDir = new File(osgiInstanceDir, "node");
114 // home cannot be overridden
115 defaults.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
116 homeDir.getAbsolutePath());
117
118 // common
119 setProp(defaults, REPO_DEFAULT_WORKSPACE, "main");
120 setProp(defaults, REPO_MAX_POOL_SIZE, "10");
121 // Jackrabbit defaults
122 setProp(defaults, REPO_BUNDLE_CACHE_MB, "8");
123 // See http://wiki.apache.org/jackrabbit/Search
124 setProp(defaults, REPO_EXTRACTOR_POOL_SIZE, "0");
125 setProp(defaults, REPO_SEARCH_CACHE_SIZE, "1000");
126 setProp(defaults, REPO_MAX_VOLATILE_INDEX_SIZE, "1048576");
127
128 // specific
129 String dburl;
130 switch (type) {
131 case h2:
132 dburl = "jdbc:h2:" + homeDir.getPath() + "/h2/repository";
133 setProp(defaults, REPO_DBURL, dburl);
134 setProp(defaults, REPO_DBUSER, "sa");
135 setProp(defaults, REPO_DBPASSWORD, "");
136 break;
137 case postgresql:
138 dburl = "jdbc:postgresql://localhost/demo";
139 setProp(defaults, REPO_DBURL, dburl);
140 setProp(defaults, REPO_DBUSER, "argeo");
141 setProp(defaults, REPO_DBPASSWORD, "argeo");
142 break;
143 case memory:
144 break;
145 default:
146 throw new CmsException("Unsupported node type " + type);
147 }
148 return defaults;
149 }
150
151 private void setProp(Dictionary<String, Object> props, String key,
152 String defaultValue) {
153 String value = prop(key, defaultValue);
154 props.put(key, value);
155 }
156
157 private String prop(String key, String defaultValue) {
158 // TODO use OSGi CM instead of Framework/System properties
159 return KernelUtils.getFrameworkProp(key, defaultValue);
160 }
161
162 private RepositoryContext createNode(JackrabbitNodeType type)
163 throws RepositoryException {
164 Hashtable<String, Object> vars = getConfigurationProperties(type);
165 RepositoryConfig repositoryConfig = getConfiguration(type, vars);
166 RepositoryContext repositoryContext = createJackrabbitRepository(repositoryConfig);
167 RepositoryImpl repository = repositoryContext.getRepository();
168
169 // cache
170 String maxCacheMbStr = prop(REPO_MAX_CACHE_MB, null);
171 if (maxCacheMbStr != null) {
172 Integer maxCacheMB = Integer.parseInt(maxCacheMbStr);
173 CacheManager cacheManager = repository.getCacheManager();
174 cacheManager.setMaxMemory(maxCacheMB * 1024l * 1024l);
175 cacheManager.setMaxMemoryPerCache((maxCacheMB / 4) * 1024l * 1024l);
176 }
177
178 // wrap the repository
179 setRepository(repository);
180 return repositoryContext;
181 }
182
183 private RepositoryContext createJackrabbitRepository(
184 RepositoryConfig repositoryConfig) throws RepositoryException {
185 File homeDirectory = null;
186 long begin = System.currentTimeMillis();
187 //
188 // Actual repository creation
189 //
190 RepositoryContext repositoryContext = RepositoryContext
191 .create(repositoryConfig);
192
193 double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
194 if (log.isTraceEnabled())
195 log.trace("Created Jackrabbit repository in " + duration
196 + " s, home: " + homeDirectory);
197
198 return repositoryContext;
199 }
200 }