1 package org
.argeo
.cms
.internal
.kernel
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
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
;
16 import javax
.jcr
.RepositoryException
;
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
.NodeConstants
;
30 import org
.argeo
.node
.RepoConf
;
31 import org
.osgi
.framework
.Constants
;
32 import org
.osgi
.service
.cm
.ConfigurationAdmin
;
33 import org
.xml
.sax
.InputSource
;
35 /** Can interpret properties in order to create an actual JCR repository. */
36 class RepositoryBuilder
{
37 private final static Log log
= LogFactory
.getLog(RepositoryBuilder
.class);
39 RepositoryContext
createRepositoryContext(Dictionary
<String
, ?
> properties
) throws RepositoryException
{
40 RepositoryConfig repositoryConfig
= createRepositoryConfig(properties
);
41 RepositoryContext repositoryContext
= createJackrabbitRepository(repositoryConfig
);
42 RepositoryImpl repository
= repositoryContext
.getRepository();
45 Object maxCacheMbStr
= prop(properties
, RepoConf
.maxCacheMB
);
46 if (maxCacheMbStr
!= null) {
47 Integer maxCacheMB
= Integer
.parseInt(maxCacheMbStr
.toString());
48 CacheManager cacheManager
= repository
.getCacheManager();
49 cacheManager
.setMaxMemory(maxCacheMB
* 1024l * 1024l);
50 cacheManager
.setMaxMemoryPerCache((maxCacheMB
/ 4) * 1024l * 1024l);
53 return repositoryContext
;
56 RepositoryConfig
createRepositoryConfig(Dictionary
<String
, ?
> properties
) throws RepositoryException
{
57 JackrabbitType type
= JackrabbitType
.valueOf(prop(properties
, RepoConf
.type
).toString());
58 ClassLoader cl
= getClass().getClassLoader();
59 InputStream in
= null;
61 final String base
= "/org/argeo/cms/internal/kernel";
64 in
= cl
.getResourceAsStream(base
+ "/repository-h2.xml");
67 in
= cl
.getResourceAsStream(base
+ "/repository-postgresql.xml");
70 in
= cl
.getResourceAsStream(base
+ "/repository-postgresql-ds.xml");
73 in
= cl
.getResourceAsStream(base
+ "/repository-memory.xml");
76 in
= cl
.getResourceAsStream(base
+ "/repository-localfs.xml");
79 throw new ArgeoJcrException("Unsupported node type " + type
);
83 throw new ArgeoJcrException("Repository configuration not found");
84 InputSource config
= new InputSource(in
);
85 Properties jackrabbitVars
= getConfigurationProperties(type
, properties
);
86 RepositoryConfig repositoryConfig
= RepositoryConfig
.create(config
, jackrabbitVars
);
87 return repositoryConfig
;
89 IOUtils
.closeQuietly(in
);
93 private Properties
getConfigurationProperties(JackrabbitType type
, Dictionary
<String
, ?
> properties
) {
94 Properties props
= new Properties();
95 for (Enumeration
<String
> keys
= properties
.keys(); keys
.hasMoreElements();) {
96 String key
= keys
.nextElement();
97 // if (key.equals(ConfigurationAdmin.SERVICE_FACTORYPID) ||
98 // key.equals(Constants.SERVICE_PID)
99 // || key.equals(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS))
102 // String value = prop(properties, RepoConf.valueOf(key));
103 // if (value != null)
104 props
.put(key
, properties
.get(key
));
105 // } catch (IllegalArgumentException e) {
106 // // ignore non RepoConf
107 // // FIXME make it more flexible/extensible
112 String homeUri
= props
.getProperty(RepoConf
.labeledUri
.name());
114 if (homeUri
== null) {
115 String cn
= props
.getProperty(NodeConstants
.CN
);
117 homePath
= KernelUtils
.getOsgiInstancePath(KernelConstants
.DIR_REPOS
+ '/' + cn
);
120 homePath
= Paths
.get(new URI(homeUri
)).toAbsolutePath();
121 } catch (URISyntaxException e
) {
122 throw new CmsException("Invalid repository home URI", e
);
125 Path rootUuidPath
= homePath
.resolve("repository/meta/rootUUID");
126 if (!Files
.exists(rootUuidPath
)) {
128 Files
.createDirectories(rootUuidPath
.getParent());
129 Files
.write(rootUuidPath
, UUID
.randomUUID().toString().getBytes());
130 } catch (IOException e
) {
131 log
.error("Could not set rootUUID", e
);
134 File homeDir
= homePath
.toFile();
136 // home cannot be overridden
137 props
.put(RepositoryConfigurationParser
.REPOSITORY_HOME_VARIABLE
, homePath
.toString());
140 setProp(props
, RepoConf
.defaultWorkspace
);
141 setProp(props
, RepoConf
.maxPoolSize
);
142 // Jackrabbit defaults
143 setProp(props
, RepoConf
.bundleCacheMB
);
144 // See http://wiki.apache.org/jackrabbit/Search
145 setProp(props
, RepoConf
.extractorPoolSize
);
146 setProp(props
, RepoConf
.searchCacheSize
);
147 setProp(props
, RepoConf
.maxVolatileIndexSize
);
153 dburl
= "jdbc:h2:" + homeDir
.getPath() + "/h2/repository";
154 setProp(props
, RepoConf
.dburl
, dburl
);
155 setProp(props
, RepoConf
.dbuser
, "sa");
156 setProp(props
, RepoConf
.dbpassword
, "");
159 dburl
= "jdbc:postgresql://localhost/demo";
160 setProp(props
, RepoConf
.dburl
, dburl
);
161 setProp(props
, RepoConf
.dbuser
, "argeo");
162 setProp(props
, RepoConf
.dbpassword
, "argeo");
169 throw new ArgeoJcrException("Unsupported node type " + type
);
174 private void setProp(Properties props
, RepoConf key
, String def
) {
175 Object value
= props
.get(key
.name());
179 value
= key
.getDefault();
181 props
.put(key
.name(), value
.toString());
184 private void setProp(Properties props
, RepoConf key
) {
185 setProp(props
, key
, null);
188 private String
prop(Dictionary
<String
, ?
> properties
, RepoConf key
) {
189 Object value
= properties
.get(key
.name());
191 return key
.getDefault() != null ? key
.getDefault().toString() : null;
193 return value
.toString();
196 private RepositoryContext
createJackrabbitRepository(RepositoryConfig repositoryConfig
) throws RepositoryException
{
197 ClassLoader currentContextCl
= Thread
.currentThread().getContextClassLoader();
198 Thread
.currentThread().setContextClassLoader(RepositoryBuilder
.class.getClassLoader());
200 long begin
= System
.currentTimeMillis();
202 // Actual repository creation
204 RepositoryContext repositoryContext
= RepositoryContext
.create(repositoryConfig
);
206 double duration
= ((double) (System
.currentTimeMillis() - begin
)) / 1000;
207 if (log
.isTraceEnabled())
209 "Created Jackrabbit repository in " + duration
+ " s, home: " + repositoryConfig
.getHomeDir());
211 return repositoryContext
;
213 Thread
.currentThread().setContextClassLoader(currentContextCl
);