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