]> git.argeo.org Git - lgpl/argeo-commons.git/blob - server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitContainer.java
clean RAP file upload classes
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jackrabbit / src / main / java / org / argeo / jackrabbit / JackrabbitContainer.java
1 /*
2 * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.argeo.jackrabbit;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.File;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Properties;
28
29 import javax.jcr.Credentials;
30 import javax.jcr.LoginException;
31 import javax.jcr.NoSuchWorkspaceException;
32 import javax.jcr.Repository;
33 import javax.jcr.RepositoryException;
34 import javax.jcr.Session;
35 import javax.jcr.Value;
36
37 import org.apache.commons.io.FileUtils;
38 import org.apache.commons.io.IOUtils;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.jackrabbit.api.JackrabbitRepository;
42 import org.apache.jackrabbit.commons.JcrUtils;
43 import org.apache.jackrabbit.commons.NamespaceHelper;
44 import org.apache.jackrabbit.commons.cnd.CndImporter;
45 import org.apache.jackrabbit.core.RepositoryImpl;
46 import org.apache.jackrabbit.core.TransientRepository;
47 import org.apache.jackrabbit.core.config.RepositoryConfig;
48 import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
49 import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory;
50 import org.argeo.ArgeoException;
51 import org.springframework.beans.factory.DisposableBean;
52 import org.springframework.beans.factory.InitializingBean;
53 import org.springframework.context.ResourceLoaderAware;
54 import org.springframework.core.io.Resource;
55 import org.springframework.core.io.ResourceLoader;
56 import org.xml.sax.InputSource;
57
58 /**
59 * Wrapper around a Jackrabbit repository which allows to configure it in Spring
60 * and expose it as a {@link Repository}.
61 */
62 public class JackrabbitContainer implements InitializingBean, DisposableBean,
63 Repository, ResourceLoaderAware {
64 private Log log = LogFactory.getLog(JackrabbitContainer.class);
65
66 private Resource configuration;
67 private File homeDirectory;
68 private Resource variables;
69
70 private Boolean inMemory = false;
71 private String uri = null;
72
73 private Repository repository;
74
75 private ResourceLoader resourceLoader;
76
77 /** Node type definitions in CND format */
78 private List<byte[]> cnds = new ArrayList<byte[]>();
79 private List<String> cndFiles = new ArrayList<String>();
80
81 /** Namespaces to register: key is prefix, value namespace */
82 private Map<String, String> namespaces = new HashMap<String, String>();
83
84 private Boolean autocreateWorkspaces = false;
85
86 public void afterPropertiesSet() throws Exception {
87 // Load cnds as resources
88 for (String resUrl : cndFiles) {
89 Resource res = resourceLoader.getResource(resUrl);
90 byte[] arr = IOUtils.toByteArray(res.getInputStream());
91 cnds.add(arr);
92 }
93
94 if (uri != null && !uri.trim().equals("")) {
95 Map<String, String> params = new HashMap<String, String>();
96 params.put(JcrUtils.REPOSITORY_URI, uri);
97 repository = new Jcr2davRepositoryFactory().getRepository(params);
98 if (repository == null)
99 throw new ArgeoException("Remote Davex repository " + uri
100 + " not found");
101 log.info("Initialized Jackrabbit repository " + repository
102 + " from uri " + uri);
103 } else {
104 if (inMemory && homeDirectory.exists()) {
105 FileUtils.deleteDirectory(homeDirectory);
106 log.warn("Deleted Jackrabbit home directory " + homeDirectory);
107 }
108
109 RepositoryConfig config;
110 InputStream in = configuration.getInputStream();
111 InputStream propsIn = null;
112 try {
113 Properties vars = new Properties();
114 if (variables != null) {
115 propsIn = variables.getInputStream();
116 vars.load(propsIn);
117 }
118 // override with system properties
119 vars.putAll(System.getProperties());
120 vars.put(
121 RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
122 homeDirectory.getCanonicalPath());
123 config = RepositoryConfig.create(new InputSource(in), vars);
124 } catch (Exception e) {
125 throw new RuntimeException("Cannot read configuration", e);
126 } finally {
127 IOUtils.closeQuietly(in);
128 IOUtils.closeQuietly(propsIn);
129 }
130
131 if (inMemory)
132 repository = new TransientRepository(config);
133 else
134 repository = RepositoryImpl.create(config);
135
136 log.info("Initialized Jackrabbit repository " + repository + " in "
137 + homeDirectory + " with config " + configuration);
138 }
139 }
140
141 public void destroy() throws Exception {
142 if (repository != null) {
143 if (repository instanceof JackrabbitRepository)
144 ((JackrabbitRepository) repository).shutdown();
145 else if (repository instanceof RepositoryImpl)
146 ((RepositoryImpl) repository).shutdown();
147 else if (repository instanceof TransientRepository)
148 ((TransientRepository) repository).shutdown();
149 }
150
151 if (inMemory)
152 if (homeDirectory.exists()) {
153 FileUtils.deleteDirectory(homeDirectory);
154 if (log.isDebugEnabled())
155 log.debug("Deleted Jackrabbit home directory "
156 + homeDirectory);
157 }
158
159 if (uri != null && !uri.trim().equals(""))
160 log.info("Destroyed Jackrabbit repository with uri " + uri);
161 else
162 log.info("Destroyed Jackrabbit repository " + repository + " in "
163 + homeDirectory + " with config " + configuration);
164 }
165
166 // JCR REPOSITORY (delegated)
167 public String getDescriptor(String key) {
168 return repository.getDescriptor(key);
169 }
170
171 public String[] getDescriptorKeys() {
172 return repository.getDescriptorKeys();
173 }
174
175 public Session login() throws LoginException, RepositoryException {
176 Session session = repository.login();
177 processNewSession(session);
178 return session;
179 }
180
181 public Session login(Credentials credentials, String workspaceName)
182 throws LoginException, NoSuchWorkspaceException,
183 RepositoryException {
184 Session session;
185 try {
186 session = repository.login(credentials, workspaceName);
187 } catch (NoSuchWorkspaceException e) {
188 if (autocreateWorkspaces)
189 session = createWorkspaceAndLogsIn(credentials, workspaceName);
190 else
191 throw e;
192 }
193 processNewSession(session);
194 return session;
195 }
196
197 public Session login(Credentials credentials) throws LoginException,
198 RepositoryException {
199 Session session = repository.login(credentials);
200 processNewSession(session);
201 return session;
202 }
203
204 public Session login(String workspaceName) throws LoginException,
205 NoSuchWorkspaceException, RepositoryException {
206 Session session;
207 try {
208 session = repository.login(workspaceName);
209 } catch (NoSuchWorkspaceException e) {
210 if (autocreateWorkspaces)
211 session = createWorkspaceAndLogsIn(null, workspaceName);
212 else
213 throw e;
214 }
215 processNewSession(session);
216 return session;
217 }
218
219 protected synchronized void processNewSession(Session session) {
220 try {
221 NamespaceHelper namespaceHelper = new NamespaceHelper(session);
222 namespaceHelper.registerNamespaces(namespaces);
223
224 for (byte[] arr : cnds)
225 CndImporter.registerNodeTypes(new InputStreamReader(
226 new ByteArrayInputStream(arr)), session, true);
227 } catch (Exception e) {
228 throw new ArgeoException("Cannot process new session", e);
229 }
230 }
231
232 /**
233 * Logs in to the default workspace, creates the required workspace, logs
234 * out, logs in to the required workspace.
235 */
236 protected Session createWorkspaceAndLogsIn(Credentials credentials,
237 String workspaceName) throws RepositoryException {
238 if (workspaceName == null)
239 throw new ArgeoException("No workspace specified.");
240 Session session = repository.login(credentials);
241 session.getWorkspace().createWorkspace(workspaceName);
242 session.logout();
243 return repository.login(credentials, workspaceName);
244 }
245
246 public void setResourceLoader(ResourceLoader resourceLoader) {
247 this.resourceLoader = resourceLoader;
248 }
249
250 public boolean isStandardDescriptor(String key) {
251 return repository.isStandardDescriptor(key);
252 }
253
254 public boolean isSingleValueDescriptor(String key) {
255 return repository.isSingleValueDescriptor(key);
256 }
257
258 public Value getDescriptorValue(String key) {
259 return repository.getDescriptorValue(key);
260 }
261
262 public Value[] getDescriptorValues(String key) {
263 return repository.getDescriptorValues(key);
264 }
265
266 // BEANS METHODS
267 public void setHomeDirectory(File homeDirectory) {
268 this.homeDirectory = homeDirectory;
269 }
270
271 public void setConfiguration(Resource configuration) {
272 this.configuration = configuration;
273 }
274
275 public void setInMemory(Boolean inMemory) {
276 this.inMemory = inMemory;
277 }
278
279 public void setNamespaces(Map<String, String> namespaces) {
280 this.namespaces = namespaces;
281 }
282
283 public void setCndFiles(List<String> cndFiles) {
284 this.cndFiles = cndFiles;
285 }
286
287 public void setVariables(Resource variables) {
288 this.variables = variables;
289 }
290
291 public void setUri(String uri) {
292 this.uri = uri;
293 }
294
295 }