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