1 package org
.argeo
.jackrabbit
;
4 import java
.io
.InputStream
;
5 import java
.util
.Dictionary
;
6 import java
.util
.Hashtable
;
8 import java
.util
.Properties
;
10 import javax
.jcr
.Credentials
;
11 import javax
.jcr
.LoginException
;
12 import javax
.jcr
.NoSuchWorkspaceException
;
13 import javax
.jcr
.RepositoryException
;
14 import javax
.jcr
.Session
;
16 import org
.apache
.commons
.io
.IOUtils
;
17 import org
.apache
.commons
.logging
.Log
;
18 import org
.apache
.commons
.logging
.LogFactory
;
19 import org
.apache
.jackrabbit
.api
.JackrabbitRepository
;
20 import org
.apache
.jackrabbit
.core
.RepositoryContext
;
21 import org
.apache
.jackrabbit
.core
.RepositoryImpl
;
22 import org
.apache
.jackrabbit
.core
.cache
.CacheManager
;
23 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfig
;
24 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfigurationParser
;
25 import org
.apache
.jackrabbit
.stats
.RepositoryStatisticsImpl
;
26 import org
.argeo
.ArgeoException
;
27 import org
.argeo
.jcr
.ArgeoJcrException
;
28 import org
.argeo
.jcr
.JcrRepositoryWrapper
;
29 import org
.argeo
.jcr
.RepoConf
;
30 import org
.osgi
.service
.cm
.ConfigurationException
;
31 import org
.osgi
.service
.cm
.ManagedService
;
32 import org
.xml
.sax
.InputSource
;
34 public class ManagedJackrabbitRepository
extends JcrRepositoryWrapper
implements ManagedService
, JackrabbitRepository
{
35 private final static Log log
= LogFactory
.getLog(ManagedJackrabbitRepository
.class);
38 final static String REPO_TYPE
= "repoType";
39 // final static String REPO_CONFIGURATION = "argeo.node.repo.configuration";
40 // final static String REPO_DEFAULT_WORKSPACE = "defaultWorkspace";
41 // final static String REPO_DBURL = "dburl";
42 // final static String REPO_DBUSER = "dbuser";
43 // final static String REPO_DBPASSWORD = "dbpassword";
44 // final static String REPO_MAX_POOL_SIZE = "maxPoolSize";
45 // final static String REPO_MAX_CACHE_MB = "maxCacheMB";
46 // final static String REPO_BUNDLE_CACHE_MB = "bundleCacheMB";
47 // final static String REPO_EXTRACTOR_POOL_SIZE = "extractorPoolSize";
48 // final static String REPO_SEARCH_CACHE_SIZE = "searchCacheSize";
49 // final static String REPO_MAX_VOLATILE_INDEX_SIZE =
50 // "maxVolatileIndexSize";
52 private Dictionary
<String
, ?
> properties
;
55 public void updated(Dictionary
<String
, ?
> properties
) throws ConfigurationException
{
56 this.properties
= properties
;
57 if (properties
== null)
60 JackrabbitNodeType type
= JackrabbitNodeType
.valueOf(prop(RepoConf
.type
).toString());
62 repositoryContext
= createNode(type
);
63 } catch (Exception e
) {
65 throw new ArgeoException("Cannot create Jackrabbit repository of type " + type
, e
);
69 private RepositoryContext repositoryContext
;
71 public ManagedJackrabbitRepository() {
72 // setBundleContext(Activator.getBundleContext());
73 // JackrabbitNodeType type = JackrabbitNodeType.valueOf(prop(REPO_TYPE,
74 // JackrabbitNodeType.h2.name()));
76 // repositoryContext = createNode(type);
77 // cndFiles = Arrays.asList(DEFAULT_CNDS);
78 // prepareDataModel();
79 // } catch (Exception e) {
80 // throw new ArgeoException("Cannot create Jackrabbit repository of type
85 public void destroy() {
86 ((RepositoryImpl
) getRepository()).shutdown();
89 RepositoryStatisticsImpl
getRepositoryStatistics() {
90 return repositoryContext
.getRepositoryStatistics();
93 private RepositoryConfig
getConfiguration(JackrabbitNodeType type
, Hashtable
<String
, Object
> props
)
94 throws RepositoryException
{
95 ClassLoader cl
= getClass().getClassLoader();
96 InputStream in
= null;
98 final String base
= "/org/argeo/jackrabbit";
101 in
= cl
.getResourceAsStream(base
+ "/repository-h2.xml");
104 in
= cl
.getResourceAsStream(base
+ "/repository-postgresql.xml");
107 in
= cl
.getResourceAsStream(base
+ "/repository-memory.xml");
110 in
= cl
.getResourceAsStream(base
+ "/repository-localfs.xml");
113 throw new ArgeoJcrException("Unsupported node type " + type
);
117 throw new ArgeoJcrException("Repository configuration not found");
118 InputSource config
= new InputSource(in
);
119 Properties jackrabbitVars
= new Properties();
120 // convert values to Strings, otherwise they are skipped
121 for (String key
: props
.keySet())
122 jackrabbitVars
.setProperty(key
, props
.get(key
).toString());
123 RepositoryConfig repositoryConfig
= RepositoryConfig
.create(config
, jackrabbitVars
);
124 return repositoryConfig
;
126 IOUtils
.closeQuietly(in
);
130 private Hashtable
<String
, Object
> getConfigurationProperties(JackrabbitNodeType type
) {
131 Hashtable
<String
, Object
> props
= new Hashtable
<String
, Object
>();
134 File osgiInstanceDir
= getOsgiInstanceDir();
135 File homeDir
= new File(osgiInstanceDir
, "repos/node");
137 // home cannot be overridden
138 props
.put(RepositoryConfigurationParser
.REPOSITORY_HOME_VARIABLE
, homeDir
.getAbsolutePath());
141 setProp(props
, RepoConf
.defaultWorkspace
);
142 setProp(props
, RepoConf
.maxPoolSize
);
143 // Jackrabbit defaults
144 setProp(props
, RepoConf
.bundleCacheMB
);
145 // See http://wiki.apache.org/jackrabbit/Search
146 setProp(props
, RepoConf
.extractorPoolSize
);
147 setProp(props
, RepoConf
.searchCacheSize
);
148 setProp(props
, RepoConf
.maxVolatileIndexSize
);
154 dburl
= "jdbc:h2:" + homeDir
.getPath() + "/h2/repository";
155 setProp(props
, RepoConf
.dburl
, dburl
);
156 setProp(props
, RepoConf
.dbuser
, "sa");
157 setProp(props
, RepoConf
.dbpassword
, "");
160 dburl
= "jdbc:postgresql://localhost/demo";
161 setProp(props
, RepoConf
.dburl
, dburl
);
162 setProp(props
, RepoConf
.dbuser
, "argeo");
163 setProp(props
, RepoConf
.dbpassword
, "argeo");
170 throw new ArgeoJcrException("Unsupported node type " + type
);
175 private void setProp(Dictionary
<String
, Object
> props
, RepoConf key
, String def
) {
176 Object value
= prop(key
);
179 props
.put(key
.name(), value
);
182 private void setProp(Dictionary
<String
, Object
> props
, RepoConf key
) {
183 setProp(props
, key
, null);
186 private Object
prop(RepoConf key
) {
187 if (properties
== null)
188 throw new ArgeoJcrException("Properties are not set");
189 Object value
= properties
.get(key
.name());
191 return key
.getDefault();
196 private RepositoryContext
createNode(JackrabbitNodeType type
) throws RepositoryException
{
197 Hashtable
<String
, Object
> props
= getConfigurationProperties(type
);
198 RepositoryConfig repositoryConfig
= getConfiguration(type
, props
);
199 RepositoryContext repositoryContext
= createJackrabbitRepository(repositoryConfig
);
200 RepositoryImpl repository
= repositoryContext
.getRepository();
203 Object maxCacheMbStr
= prop(RepoConf
.maxCacheMB
);
204 if (maxCacheMbStr
!= null) {
205 Integer maxCacheMB
= Integer
.parseInt(maxCacheMbStr
.toString());
206 CacheManager cacheManager
= repository
.getCacheManager();
207 cacheManager
.setMaxMemory(maxCacheMB
* 1024l * 1024l);
208 cacheManager
.setMaxMemoryPerCache((maxCacheMB
/ 4) * 1024l * 1024l);
211 // wrap the repository
212 setRepository(repository
);
213 return repositoryContext
;
216 private RepositoryContext
createJackrabbitRepository(RepositoryConfig repositoryConfig
) throws RepositoryException
{
217 ClassLoader currentContextCl
= Thread
.currentThread().getContextClassLoader();
218 Thread
.currentThread().setContextClassLoader(ManagedJackrabbitRepository
.class.getClassLoader());
220 long begin
= System
.currentTimeMillis();
222 // Actual repository creation
224 RepositoryContext repositoryContext
= RepositoryContext
.create(repositoryConfig
);
226 double duration
= ((double) (System
.currentTimeMillis() - begin
)) / 1000;
227 if (log
.isTraceEnabled())
229 "Created Jackrabbit repository in " + duration
+ " s, home: " + repositoryConfig
.getHomeDir());
231 return repositoryContext
;
233 Thread
.currentThread().setContextClassLoader(currentContextCl
);
241 public synchronized void waitForInit() {
242 while (repositoryContext
== null)
245 } catch (InterruptedException e
) {
250 private final static String OSGI_INSTANCE_AREA
= "osgi.instance.area";
252 private File
getOsgiInstanceDir() {
253 String instanceArea
= System
.getProperty(OSGI_INSTANCE_AREA
);
254 return new File(instanceArea
.substring("file:".length())).getAbsoluteFile();
258 public Session
login(Credentials credentials
, String workspaceName
, Map
<String
, Object
> attributes
)
259 throws LoginException
, NoSuchWorkspaceException
, RepositoryException
{
260 // TODO Auto-generated method stub
265 public void shutdown() {