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
.osgi
.framework
.BundleContext
;
28 import org
.xml
.sax
.InputSource
;
30 /** Jacrabbit based data layer */
31 class NodeRepository
extends JackrabbitWrapper
implements KernelConstants
,
33 private static Log log
= LogFactory
.getLog(NodeRepository
.class);
35 private RepositoryContext repositoryContext
;
37 public NodeRepository(BundleContext bundleContext
) {
38 setBundleContext(bundleContext
);
39 JackrabbitNodeType type
= JackrabbitNodeType
.valueOf(prop(REPO_TYPE
,
42 repositoryContext
= createNode(type
);
43 setCndFiles(Arrays
.asList(DEFAULT_CNDS
));
45 } catch (Exception e
) {
46 throw new ArgeoException(
47 "Cannot create Jackrabbit repository of type " + type
, e
);
51 public void destroy() {
52 ((RepositoryImpl
) getRepository()).shutdown();
55 RepositoryStatisticsImpl
getRepositoryStatistics() {
56 return repositoryContext
.getRepositoryStatistics();
59 private RepositoryConfig
getConfiguration(JackrabbitNodeType type
,
60 Hashtable
<String
, Object
> vars
) throws RepositoryException
{
61 ClassLoader cl
= getClass().getClassLoader();
62 InputStream in
= null;
64 final String base
= "/org/argeo/cms/internal/kernel";
67 in
= cl
.getResourceAsStream(base
+ "/repository-h2.xml");
70 in
= cl
.getResourceAsStream(base
+ "/repository-postgresql.xml");
73 in
= cl
.getResourceAsStream(base
+ "/repository-memory.xml");
76 throw new CmsException("Unsupported node type " + type
);
80 throw new CmsException("Repository configuration not found");
81 InputSource config
= new InputSource(in
);
82 Properties jackrabbitProps
= new Properties();
83 jackrabbitProps
.putAll(vars
);
84 RepositoryConfig repositoryConfig
= RepositoryConfig
.create(config
,
86 return repositoryConfig
;
88 IOUtils
.closeQuietly(in
);
92 private Hashtable
<String
, Object
> getConfigurationProperties(
93 JackrabbitNodeType type
) {
94 // use Hashtable to ease integration with Properties
95 Hashtable
<String
, Object
> defaults
= new Hashtable
<String
, Object
>();
98 File osgiInstanceDir
= KernelUtils
.getOsgiInstanceDir();
99 File homeDir
= new File(osgiInstanceDir
, "node");
100 // home cannot be overridden
101 defaults
.put(RepositoryConfigurationParser
.REPOSITORY_HOME_VARIABLE
,
102 homeDir
.getAbsolutePath());
105 setProp(defaults
, REPO_DEFAULT_WORKSPACE
, "main");
106 setProp(defaults
, REPO_MAX_POOL_SIZE
, "10");
107 // Jackrabbit defaults
108 setProp(defaults
, REPO_BUNDLE_CACHE_MB
, "8");
109 // See http://wiki.apache.org/jackrabbit/Search
110 setProp(defaults
, REPO_EXTRACTOR_POOL_SIZE
, "0");
111 setProp(defaults
, REPO_SEARCH_CACHE_SIZE
, "1000");
112 setProp(defaults
, REPO_MAX_VOLATILE_INDEX_SIZE
, "1048576");
118 dburl
= "jdbc:h2:" + homeDir
.getPath() + "/h2/repository";
119 setProp(defaults
, REPO_DBURL
, dburl
);
120 setProp(defaults
, REPO_DBUSER
, "sa");
121 setProp(defaults
, REPO_DBPASSWORD
, "");
124 dburl
= "jdbc:postgresql://localhost/demo";
125 setProp(defaults
, REPO_DBURL
, dburl
);
126 setProp(defaults
, REPO_DBUSER
, "argeo");
127 setProp(defaults
, REPO_DBPASSWORD
, "argeo");
132 throw new CmsException("Unsupported node type " + type
);
137 private void setProp(Dictionary
<String
, Object
> props
, String key
,
138 String defaultValue
) {
139 String value
= prop(key
, defaultValue
);
140 props
.put(key
, value
);
143 private String
prop(String key
, String defaultValue
) {
144 // TODO use OSGi CM instead of Framework/System properties
145 return KernelUtils
.getFrameworkProp(key
, defaultValue
);
148 private RepositoryContext
createNode(JackrabbitNodeType type
)
149 throws RepositoryException
{
150 Hashtable
<String
, Object
> vars
= getConfigurationProperties(type
);
151 RepositoryConfig repositoryConfig
= getConfiguration(type
, vars
);
152 RepositoryContext repositoryContext
= createJackrabbitRepository(repositoryConfig
);
153 RepositoryImpl repository
= repositoryContext
.getRepository();
156 String maxCacheMbStr
= prop(REPO_MAX_CACHE_MB
, null);
157 if (maxCacheMbStr
!= null) {
158 Integer maxCacheMB
= Integer
.parseInt(maxCacheMbStr
);
159 CacheManager cacheManager
= repository
.getCacheManager();
160 cacheManager
.setMaxMemory(maxCacheMB
* 1024l * 1024l);
161 cacheManager
.setMaxMemoryPerCache((maxCacheMB
/ 4) * 1024l * 1024l);
164 // wrap the repository
165 setRepository(repository
);
166 return repositoryContext
;
169 private RepositoryContext
createJackrabbitRepository(
170 RepositoryConfig repositoryConfig
) throws RepositoryException
{
171 File homeDirectory
= null;
172 long begin
= System
.currentTimeMillis();
174 // Actual repository creation
176 RepositoryContext repositoryContext
= RepositoryContext
177 .create(repositoryConfig
);
179 double duration
= ((double) (System
.currentTimeMillis() - begin
)) / 1000;
180 if (log
.isTraceEnabled())
181 log
.trace("Created Jackrabbit repository in " + duration
182 + " s, home: " + homeDirectory
);
184 return repositoryContext
;