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
.Repository
;
13 import javax
.jcr
.RepositoryException
;
15 import org
.apache
.commons
.io
.IOUtils
;
16 import org
.apache
.commons
.logging
.Log
;
17 import org
.apache
.commons
.logging
.LogFactory
;
18 import org
.apache
.jackrabbit
.core
.RepositoryContext
;
19 import org
.apache
.jackrabbit
.core
.RepositoryImpl
;
20 import org
.apache
.jackrabbit
.core
.cache
.CacheManager
;
21 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfig
;
22 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfigurationParser
;
23 import org
.apache
.jackrabbit
.stats
.RepositoryStatisticsImpl
;
24 import org
.argeo
.ArgeoException
;
25 import org
.argeo
.cms
.CmsException
;
26 import org
.argeo
.jackrabbit
.JackrabbitWrapper
;
27 import org
.argeo
.jcr
.ArgeoJcrConstants
;
28 import org
.argeo
.jcr
.DefaultRepositoryRegister
;
29 import org
.osgi
.framework
.BundleContext
;
30 import org
.osgi
.framework
.ServiceRegistration
;
31 import org
.xml
.sax
.InputSource
;
33 /** Jacrabbit based data layer */
34 class JackrabbitNode
extends JackrabbitWrapper
implements KernelConstants
,
36 private static Log log
= LogFactory
.getLog(JackrabbitNode
.class);
38 private RepositoryContext repositoryContext
;
40 private ServiceRegistration
<Repository
> repositoryReg
;
42 public JackrabbitNode(BundleContext bundleContext
) {
43 setBundleContext(bundleContext
);
44 JackrabbitNodeType type
= JackrabbitNodeType
.valueOf(prop(REPO_TYPE
,
47 repositoryContext
= createNode(type
);
48 setCndFiles(Arrays
.asList(DEFAULT_CNDS
));
50 } catch (Exception e
) {
51 throw new ArgeoException(
52 "Cannot create Jackrabbit repository of type " + type
, e
);
56 void publish(DefaultRepositoryRegister repositoryRegister
) {
57 Hashtable
<String
, String
> regProps
= new Hashtable
<String
, String
>();
58 regProps
.put(JCR_REPOSITORY_ALIAS
, ALIAS_NODE
);
59 repositoryReg
= getBundleContext().registerService(Repository
.class,
61 repositoryRegister
.register(this, regProps
);
64 public void destroy() {
65 repositoryReg
.unregister();
66 ((RepositoryImpl
) getRepository()).shutdown();
69 RepositoryStatisticsImpl
getRepositoryStatistics() {
70 return repositoryContext
.getRepositoryStatistics();
73 private RepositoryConfig
getConfiguration(JackrabbitNodeType type
,
74 Hashtable
<String
, Object
> vars
) throws RepositoryException
{
75 ClassLoader cl
= getClass().getClassLoader();
76 InputStream in
= null;
78 final String base
= "/org/argeo/cms/internal/kernel";
81 in
= cl
.getResourceAsStream(base
+ "/repository-h2.xml");
84 in
= cl
.getResourceAsStream(base
+ "/repository-postgresql.xml");
87 in
= cl
.getResourceAsStream(base
+ "/repository-memory.xml");
90 throw new CmsException("Unsupported node type " + type
);
94 throw new CmsException("Repository configuration not found");
95 InputSource config
= new InputSource(in
);
96 Properties jackrabbitProps
= new Properties();
97 jackrabbitProps
.putAll(vars
);
98 RepositoryConfig repositoryConfig
= RepositoryConfig
.create(config
,
100 return repositoryConfig
;
102 IOUtils
.closeQuietly(in
);
106 private Hashtable
<String
, Object
> getConfigurationProperties(
107 JackrabbitNodeType type
) {
108 // use Hashtable to ease integration with Properties
109 Hashtable
<String
, Object
> defaults
= new Hashtable
<String
, Object
>();
112 File osgiInstanceDir
= KernelUtils
.getOsgiInstanceDir();
113 File homeDir
= new File(osgiInstanceDir
, "node");
114 // home cannot be overridden
115 defaults
.put(RepositoryConfigurationParser
.REPOSITORY_HOME_VARIABLE
,
116 homeDir
.getAbsolutePath());
119 setProp(defaults
, REPO_DEFAULT_WORKSPACE
, "main");
120 setProp(defaults
, REPO_MAX_POOL_SIZE
, "10");
121 // Jackrabbit defaults
122 setProp(defaults
, REPO_BUNDLE_CACHE_MB
, "8");
123 // See http://wiki.apache.org/jackrabbit/Search
124 setProp(defaults
, REPO_EXTRACTOR_POOL_SIZE
, "0");
125 setProp(defaults
, REPO_SEARCH_CACHE_SIZE
, "1000");
126 setProp(defaults
, REPO_MAX_VOLATILE_INDEX_SIZE
, "1048576");
132 dburl
= "jdbc:h2:" + homeDir
.getPath() + "/h2/repository";
133 setProp(defaults
, REPO_DBURL
, dburl
);
134 setProp(defaults
, REPO_DBUSER
, "sa");
135 setProp(defaults
, REPO_DBPASSWORD
, "");
138 dburl
= "jdbc:postgresql://localhost/demo";
139 setProp(defaults
, REPO_DBURL
, dburl
);
140 setProp(defaults
, REPO_DBUSER
, "argeo");
141 setProp(defaults
, REPO_DBPASSWORD
, "argeo");
146 throw new CmsException("Unsupported node type " + type
);
151 private void setProp(Dictionary
<String
, Object
> props
, String key
,
152 String defaultValue
) {
153 String value
= prop(key
, defaultValue
);
154 props
.put(key
, value
);
157 private String
prop(String key
, String defaultValue
) {
158 // TODO use OSGi CM instead of Framework/System properties
159 return KernelUtils
.getFrameworkProp(key
, defaultValue
);
162 private RepositoryContext
createNode(JackrabbitNodeType type
)
163 throws RepositoryException
{
164 Hashtable
<String
, Object
> vars
= getConfigurationProperties(type
);
165 RepositoryConfig repositoryConfig
= getConfiguration(type
, vars
);
166 RepositoryContext repositoryContext
= createJackrabbitRepository(repositoryConfig
);
167 RepositoryImpl repository
= repositoryContext
.getRepository();
170 String maxCacheMbStr
= prop(REPO_MAX_CACHE_MB
, null);
171 if (maxCacheMbStr
!= null) {
172 Integer maxCacheMB
= Integer
.parseInt(maxCacheMbStr
);
173 CacheManager cacheManager
= repository
.getCacheManager();
174 cacheManager
.setMaxMemory(maxCacheMB
* 1024l * 1024l);
175 cacheManager
.setMaxMemoryPerCache((maxCacheMB
/ 4) * 1024l * 1024l);
178 // wrap the repository
179 setRepository(repository
);
180 return repositoryContext
;
183 private RepositoryContext
createJackrabbitRepository(
184 RepositoryConfig repositoryConfig
) throws RepositoryException
{
185 File homeDirectory
= null;
186 long begin
= System
.currentTimeMillis();
188 // Actual repository creation
190 RepositoryContext repositoryContext
= RepositoryContext
191 .create(repositoryConfig
);
193 double duration
= ((double) (System
.currentTimeMillis() - begin
)) / 1000;
194 if (log
.isTraceEnabled())
195 log
.trace("Created Jackrabbit repository in " + duration
196 + " s, home: " + homeDirectory
);
198 return repositoryContext
;