]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/kernel/RepositoryBuilder.java
Re-add org.argeo.cms.util.useradmin
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / RepositoryBuilder.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.net.URI;
7 import java.net.URISyntaxException;
8 import java.nio.file.Files;
9 import java.nio.file.Path;
10 import java.nio.file.Paths;
11 import java.util.Dictionary;
12 import java.util.Enumeration;
13 import java.util.Properties;
14 import java.util.UUID;
15
16 import javax.jcr.RepositoryException;
17
18 import org.apache.commons.io.IOUtils;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.jackrabbit.core.RepositoryContext;
22 import org.apache.jackrabbit.core.RepositoryImpl;
23 import org.apache.jackrabbit.core.cache.CacheManager;
24 import org.apache.jackrabbit.core.config.RepositoryConfig;
25 import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
26 import org.argeo.cms.CmsException;
27 import org.argeo.jcr.ArgeoJcrConstants;
28 import org.argeo.jcr.ArgeoJcrException;
29 import org.argeo.node.RepoConf;
30 import org.osgi.framework.Constants;
31 import org.osgi.service.cm.ConfigurationAdmin;
32 import org.xml.sax.InputSource;
33
34 /** Can interpret properties in order to create an actual JCR repository. */
35 class RepositoryBuilder {
36 private final static Log log = LogFactory.getLog(RepositoryBuilder.class);
37
38 RepositoryContext createRepositoryContext(Dictionary<String, ?> properties) throws RepositoryException {
39 RepositoryConfig repositoryConfig = createRepositoryConfig(properties);
40 RepositoryContext repositoryContext = createJackrabbitRepository(repositoryConfig);
41 RepositoryImpl repository = repositoryContext.getRepository();
42
43 // cache
44 Object maxCacheMbStr = prop(properties, RepoConf.maxCacheMB);
45 if (maxCacheMbStr != null) {
46 Integer maxCacheMB = Integer.parseInt(maxCacheMbStr.toString());
47 CacheManager cacheManager = repository.getCacheManager();
48 cacheManager.setMaxMemory(maxCacheMB * 1024l * 1024l);
49 cacheManager.setMaxMemoryPerCache((maxCacheMB / 4) * 1024l * 1024l);
50 }
51
52 return repositoryContext;
53 }
54
55 RepositoryConfig createRepositoryConfig(Dictionary<String, ?> properties) throws RepositoryException {
56 JackrabbitType type = JackrabbitType.valueOf(prop(properties, RepoConf.type).toString());
57 ClassLoader cl = getClass().getClassLoader();
58 InputStream in = null;
59 try {
60 final String base = "/org/argeo/cms/internal/kernel";
61 switch (type) {
62 case h2:
63 in = cl.getResourceAsStream(base + "/repository-h2.xml");
64 break;
65 case postgresql:
66 in = cl.getResourceAsStream(base + "/repository-postgresql.xml");
67 break;
68 case postgresql_ds:
69 in = cl.getResourceAsStream(base + "/repository-postgresql-ds.xml");
70 break;
71 case memory:
72 in = cl.getResourceAsStream(base + "/repository-memory.xml");
73 break;
74 case localfs:
75 in = cl.getResourceAsStream(base + "/repository-localfs.xml");
76 break;
77 default:
78 throw new ArgeoJcrException("Unsupported node type " + type);
79 }
80
81 if (in == null)
82 throw new ArgeoJcrException("Repository configuration not found");
83 InputSource config = new InputSource(in);
84 Properties jackrabbitVars = getConfigurationProperties(type, properties);
85 RepositoryConfig repositoryConfig = RepositoryConfig.create(config, jackrabbitVars);
86 return repositoryConfig;
87 } finally {
88 IOUtils.closeQuietly(in);
89 }
90 }
91
92 private Properties getConfigurationProperties(JackrabbitType type, Dictionary<String, ?> properties) {
93 Properties props = new Properties();
94 keys: for (Enumeration<String> keys = properties.keys(); keys.hasMoreElements();) {
95 String key = keys.nextElement();
96 if (key.equals(ConfigurationAdmin.SERVICE_FACTORYPID) || key.equals(Constants.SERVICE_PID)
97 || key.equals(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS))
98 continue keys;
99 String value = prop(properties, RepoConf.valueOf(key));
100 if (value != null)
101 props.put(key, value);
102 }
103
104 // home
105 String homeUri = props.getProperty(RepoConf.labeledUri.name());
106 Path homePath;
107 try {
108 homePath = Paths.get(new URI(homeUri)).toAbsolutePath();
109 } catch (URISyntaxException e) {
110 throw new CmsException("Invalid repository home URI", e);
111 }
112 Path rootUuidPath = homePath.resolve("repository/meta/rootUUID");
113 if (!Files.exists(rootUuidPath)) {
114 try {
115 Files.createDirectories(rootUuidPath.getParent());
116 Files.write(rootUuidPath, UUID.randomUUID().toString().getBytes());
117 } catch (IOException e) {
118 log.error("Could not set rootUUID", e);
119 }
120 }
121 File homeDir = homePath.toFile();
122 homeDir.mkdirs();
123 // home cannot be overridden
124 props.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, homePath.toString());
125
126 // common
127 setProp(props, RepoConf.defaultWorkspace);
128 setProp(props, RepoConf.maxPoolSize);
129 // Jackrabbit defaults
130 setProp(props, RepoConf.bundleCacheMB);
131 // See http://wiki.apache.org/jackrabbit/Search
132 setProp(props, RepoConf.extractorPoolSize);
133 setProp(props, RepoConf.searchCacheSize);
134 setProp(props, RepoConf.maxVolatileIndexSize);
135
136 // specific
137 String dburl;
138 switch (type) {
139 case h2:
140 dburl = "jdbc:h2:" + homeDir.getPath() + "/h2/repository";
141 setProp(props, RepoConf.dburl, dburl);
142 setProp(props, RepoConf.dbuser, "sa");
143 setProp(props, RepoConf.dbpassword, "");
144 break;
145 case postgresql:
146 dburl = "jdbc:postgresql://localhost/demo";
147 setProp(props, RepoConf.dburl, dburl);
148 setProp(props, RepoConf.dbuser, "argeo");
149 setProp(props, RepoConf.dbpassword, "argeo");
150 break;
151 case memory:
152 break;
153 case localfs:
154 break;
155 default:
156 throw new ArgeoJcrException("Unsupported node type " + type);
157 }
158 return props;
159 }
160
161 private void setProp(Properties props, RepoConf key, String def) {
162 Object value = props.get(key.name());
163 if (value == null)
164 value = def;
165 if (value == null)
166 value = key.getDefault();
167 if (value != null)
168 props.put(key.name(), value.toString());
169 }
170
171 private void setProp(Properties props, RepoConf key) {
172 setProp(props, key, null);
173 }
174
175 private String prop(Dictionary<String, ?> properties, RepoConf key) {
176 Object value = properties.get(key.name());
177 if (value == null)
178 return key.getDefault() != null ? key.getDefault().toString() : null;
179 else
180 return value.toString();
181 }
182
183 private RepositoryContext createJackrabbitRepository(RepositoryConfig repositoryConfig) throws RepositoryException {
184 ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
185 Thread.currentThread().setContextClassLoader(RepositoryBuilder.class.getClassLoader());
186 try {
187 long begin = System.currentTimeMillis();
188 //
189 // Actual repository creation
190 //
191 RepositoryContext repositoryContext = RepositoryContext.create(repositoryConfig);
192
193 double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
194 if (log.isTraceEnabled())
195 log.trace(
196 "Created Jackrabbit repository in " + duration + " s, home: " + repositoryConfig.getHomeDir());
197
198 return repositoryContext;
199 } finally {
200 Thread.currentThread().setContextClassLoader(currentContextCl);
201 }
202 }
203
204 }