1 package org.argeo.cms.internal.kernel;
2
3 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX;
4
5 import java.io.IOException;
6 import java.net.URI;
7 import java.nio.file.Files;
8 import java.nio.file.Path;
9 import java.util.Dictionary;
10 import java.util.HashMap;
11 import java.util.Hashtable;
12 import java.util.Map;
13
14 import javax.jcr.Repository;
15 import javax.jcr.RepositoryFactory;
16 import javax.servlet.Servlet;
17 import javax.servlet.ServletException;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.jackrabbit.core.RepositoryContext;
22 import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet;
23 import org.argeo.api.NodeConstants;
24 import org.argeo.cms.CmsException;
25 import org.argeo.cms.internal.http.CmsRemotingServlet;
26 import org.argeo.cms.internal.http.HttpUtils;
27 import org.argeo.cms.internal.jcr.RepoConf;
28 import org.argeo.cms.internal.jcr.RepositoryBuilder;
29 import org.argeo.util.LangUtils;
30 import org.osgi.framework.BundleContext;
31 import org.osgi.framework.Constants;
32 import org.osgi.framework.FrameworkUtil;
33 import org.osgi.service.cm.ConfigurationException;
34 import org.osgi.service.cm.ManagedServiceFactory;
35 import org.osgi.service.http.NamespaceException;
36 import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
37
38
39 class RepositoryServiceFactory implements ManagedServiceFactory {
40 private final static Log log = LogFactory.getLog(RepositoryServiceFactory.class);
41 private final BundleContext bc = FrameworkUtil.getBundle(RepositoryServiceFactory.class).getBundleContext();
42
43 private Map<String, RepositoryContext> repositories = new HashMap<String, RepositoryContext>();
44 private Map<String, Object> pidToCn = new HashMap<String, Object>();
45
46 @Override
47 public String getName() {
48 return "Jackrabbit repository service factory";
49 }
50
51 @Override
52 public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
53 if (repositories.containsKey(pid))
54 throw new CmsException("Already a repository registered for " + pid);
55
56 if (properties == null)
57 return;
58
59 if (repositories.containsKey(pid)) {
60 log.warn("Ignore update of Jackrabbit repository " + pid);
61 return;
62 }
63
64 try {
65 Object labeledUri = properties.get(RepoConf.labeledUri.name());
66 if (labeledUri == null) {
67 RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
68 RepositoryContext repositoryContext = repositoryBuilder.createRepositoryContext(properties);
69 repositories.put(pid, repositoryContext);
70 Dictionary<String, Object> props = LangUtils.dico(Constants.SERVICE_PID, pid);
71
72
73 Object cn = properties.get(NodeConstants.CN);
74 if (cn != null) {
75 props.put(NodeConstants.CN, cn);
76
77 pidToCn.put(pid, cn);
78 }
79 bc.registerService(RepositoryContext.class, repositoryContext, props);
80 } else {
81 try {
82 Object cn = properties.get(NodeConstants.CN);
83 Object defaultWorkspace = properties.get(RepoConf.defaultWorkspace.name());
84 if (defaultWorkspace == null)
85 defaultWorkspace = RepoConf.defaultWorkspace.getDefault();
86 URI uri = new URI(labeledUri.toString());
87 RepositoryFactory repositoryFactory = bc
88 .getService(bc.getServiceReference(RepositoryFactory.class));
89 Map<String, String> parameters = new HashMap<String, String>();
90 parameters.put(RepoConf.labeledUri.name(), uri.toString());
91 parameters.put(RepoConf.defaultWorkspace.name(), defaultWorkspace.toString());
92 Repository repository = repositoryFactory.getRepository(parameters);
93
94
95 Dictionary<String, Object> props = LangUtils.dico(Constants.SERVICE_PID, pid);
96 props.put(RepoConf.labeledUri.name(),
97 new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null)
98 .toString());
99 if (cn != null) {
100 props.put(NodeConstants.CN, cn);
101
102 pidToCn.put(pid, cn);
103 }
104 bc.registerService(Repository.class, repository, props);
105
106
107 if (cn.equals(NodeConstants.NODE_REPOSITORY)) {
108 Dictionary<String, Object> homeProps = LangUtils.dico(NodeConstants.CN,
109 NodeConstants.EGO_REPOSITORY);
110 EgoRepository homeRepository = new EgoRepository(repository, true);
111 bc.registerService(Repository.class, homeRepository, homeProps);
112 }
113 } catch (Exception e) {
114
115 e.printStackTrace();
116 }
117 }
118 } catch (Exception e) {
119 throw new CmsException("Cannot create Jackrabbit repository " + pid, e);
120 }
121
122 }
123
124 @Override
125 public void deleted(String pid) {
126 RepositoryContext repositoryContext = repositories.remove(pid);
127 repositoryContext.getRepository().shutdown();
128 if (log.isDebugEnabled())
129 log.debug("Deleted repository " + pid);
130 }
131
132 public void shutdown() {
133 for (String pid : repositories.keySet()) {
134 try {
135 repositories.get(pid).getRepository().shutdown();
136 if (log.isDebugEnabled())
137 log.debug("Shut down repository " + pid
138 + (pidToCn.containsKey(pid) ? " (" + pidToCn.get(pid) + ")" : ""));
139 } catch (Exception e) {
140 log.error("Error when shutting down Jackrabbit repository " + pid, e);
141 }
142 }
143 }
144
145 }