1 package org
.argeo
.cms
.internal
.kernel
;
3 import static org
.argeo
.cms
.internal
.kernel
.JackrabbitNodeType
.h2
;
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
;
12 import javax
.jcr
.RepositoryException
;
14 import org
.apache
.commons
.io
.IOUtils
;
15 import org
.apache
.commons
.logging
.Log
;
16 import org
.apache
.commons
.logging
.LogFactory
;
17 import org
.apache
.jackrabbit
.core
.RepositoryContext
;
18 import org
.apache
.jackrabbit
.core
.RepositoryImpl
;
19 import org
.apache
.jackrabbit
.core
.cache
.CacheManager
;
20 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfig
;
21 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfigurationParser
;
22 import org
.apache
.jackrabbit
.stats
.RepositoryStatisticsImpl
;
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
.xml
.sax
.InputSource
;
29 /** Jacrabbit based data layer */
30 class NodeRepository
extends JackrabbitWrapper
implements KernelConstants
,
32 private static Log log
= LogFactory
.getLog(NodeRepository
.class);
34 private RepositoryContext repositoryContext
;
36 public NodeRepository() {
37 setBundleContext(Activator
.getBundleContext());
38 JackrabbitNodeType type
= JackrabbitNodeType
.valueOf(prop(REPO_TYPE
,
41 repositoryContext
= createNode(type
);
42 setCndFiles(Arrays
.asList(DEFAULT_CNDS
));
44 } catch (Exception e
) {
45 throw new ArgeoException(
46 "Cannot create Jackrabbit repository of type " + type
, e
);
50 public void destroy() {
51 ((RepositoryImpl
) getRepository()).shutdown();
54 RepositoryStatisticsImpl
getRepositoryStatistics() {
55 return repositoryContext
.getRepositoryStatistics();
58 private RepositoryConfig
getConfiguration(JackrabbitNodeType type
,
59 Hashtable
<String
, Object
> vars
) throws RepositoryException
{
60 ClassLoader cl
= getClass().getClassLoader();
61 InputStream in
= null;
63 final String base
= "/org/argeo/cms/internal/kernel";
66 in
= cl
.getResourceAsStream(base
+ "/repository-h2.xml");
69 in
= cl
.getResourceAsStream(base
+ "/repository-postgresql.xml");
72 in
= cl
.getResourceAsStream(base
+ "/repository-memory.xml");
75 throw new CmsException("Unsupported node type " + type
);
79 throw new CmsException("Repository configuration not found");
80 InputSource config
= new InputSource(in
);
81 Properties jackrabbitProps
= new Properties();
82 jackrabbitProps
.putAll(vars
);
83 RepositoryConfig repositoryConfig
= RepositoryConfig
.create(config
,
85 return repositoryConfig
;
87 IOUtils
.closeQuietly(in
);
91 private Hashtable
<String
, Object
> getConfigurationProperties(
92 JackrabbitNodeType type
) {
93 // use Hashtable to ease integration with Properties
94 Hashtable
<String
, Object
> defaults
= new Hashtable
<String
, Object
>();
97 File osgiInstanceDir
= KernelUtils
.getOsgiInstanceDir();
98 File homeDir
= new File(osgiInstanceDir
, DIR_NODE
);
99 // home cannot be overridden
100 defaults
.put(RepositoryConfigurationParser
.REPOSITORY_HOME_VARIABLE
,
101 homeDir
.getAbsolutePath());
104 setProp(defaults
, REPO_DEFAULT_WORKSPACE
, "main");
105 setProp(defaults
, REPO_MAX_POOL_SIZE
, "10");
106 // Jackrabbit defaults
107 setProp(defaults
, REPO_BUNDLE_CACHE_MB
, "8");
108 // See http://wiki.apache.org/jackrabbit/Search
109 setProp(defaults
, REPO_EXTRACTOR_POOL_SIZE
, "0");
110 setProp(defaults
, REPO_SEARCH_CACHE_SIZE
, "1000");
111 setProp(defaults
, REPO_MAX_VOLATILE_INDEX_SIZE
, "1048576");
117 dburl
= "jdbc:h2:" + homeDir
.getPath() + "/h2/repository";
118 setProp(defaults
, REPO_DBURL
, dburl
);
119 setProp(defaults
, REPO_DBUSER
, "sa");
120 setProp(defaults
, REPO_DBPASSWORD
, "");
123 dburl
= "jdbc:postgresql://localhost/demo";
124 setProp(defaults
, REPO_DBURL
, dburl
);
125 setProp(defaults
, REPO_DBUSER
, "argeo");
126 setProp(defaults
, REPO_DBPASSWORD
, "argeo");
131 throw new CmsException("Unsupported node type " + type
);
136 private void setProp(Dictionary
<String
, Object
> props
, String key
,
137 String defaultValue
) {
138 String value
= prop(key
, defaultValue
);
139 props
.put(key
, value
);
142 private String
prop(String key
, String defaultValue
) {
143 // TODO use OSGi CM instead of Framework/System properties
144 return KernelUtils
.getFrameworkProp(key
, defaultValue
);
147 private RepositoryContext
createNode(JackrabbitNodeType type
)
148 throws RepositoryException
{
149 Hashtable
<String
, Object
> vars
= getConfigurationProperties(type
);
150 RepositoryConfig repositoryConfig
= getConfiguration(type
, vars
);
151 RepositoryContext repositoryContext
= createJackrabbitRepository(repositoryConfig
);
152 RepositoryImpl repository
= repositoryContext
.getRepository();
155 String maxCacheMbStr
= prop(REPO_MAX_CACHE_MB
, null);
156 if (maxCacheMbStr
!= null) {
157 Integer maxCacheMB
= Integer
.parseInt(maxCacheMbStr
);
158 CacheManager cacheManager
= repository
.getCacheManager();
159 cacheManager
.setMaxMemory(maxCacheMB
* 1024l * 1024l);
160 cacheManager
.setMaxMemoryPerCache((maxCacheMB
/ 4) * 1024l * 1024l);
163 // wrap the repository
164 setRepository(repository
);
165 return repositoryContext
;
168 private RepositoryContext
createJackrabbitRepository(
169 RepositoryConfig repositoryConfig
) throws RepositoryException
{
170 long begin
= System
.currentTimeMillis();
172 // Actual repository creation
174 RepositoryContext repositoryContext
= RepositoryContext
175 .create(repositoryConfig
);
177 double duration
= ((double) (System
.currentTimeMillis() - begin
)) / 1000;
178 if (log
.isTraceEnabled())
179 log
.trace("Created Jackrabbit repository in " + duration
180 + " s, home: " + repositoryConfig
.getHomeDir());
182 return repositoryContext
;