]> git.argeo.org Git - lgpl/argeo-commons.git/blob - jcr/internal/RepositoryContextsFactory.java
Prepare next development cycle
[lgpl/argeo-commons.git] / jcr / internal / RepositoryContextsFactory.java
1 package org.argeo.cms.jcr.internal;
2
3 import java.io.IOException;
4 import java.net.URI;
5 import java.net.URISyntaxException;
6 import java.util.Dictionary;
7 import java.util.HashMap;
8 import java.util.Map;
9
10 import javax.jcr.Repository;
11 import javax.jcr.RepositoryException;
12 import javax.jcr.RepositoryFactory;
13
14 import org.apache.jackrabbit.core.RepositoryContext;
15 import org.argeo.api.cms.CmsConstants;
16 import org.argeo.api.cms.CmsLog;
17 import org.argeo.cms.internal.jcr.RepoConf;
18 import org.argeo.cms.internal.jcr.RepositoryBuilder;
19 import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator;
20 import org.argeo.util.LangUtils;
21 import org.osgi.framework.Constants;
22 import org.osgi.service.cm.ConfigurationException;
23 import org.osgi.service.cm.ManagedServiceFactory;
24
25 /** A {@link ManagedServiceFactory} creating or referencing JCR repositories. */
26 public class RepositoryContextsFactory implements ManagedServiceFactory {
27 private final static CmsLog log = CmsLog.getLog(RepositoryContextsFactory.class);
28 // private final BundleContext bc = FrameworkUtil.getBundle(RepositoryServiceFactory.class).getBundleContext();
29
30 private Map<String, RepositoryContext> repositories = new HashMap<String, RepositoryContext>();
31 private Map<String, Object> pidToCn = new HashMap<String, Object>();
32
33 public void init() {
34
35 }
36
37 public void destroy() {
38 for (String pid : repositories.keySet()) {
39 try {
40 RepositoryContext repositoryContext = repositories.get(pid);
41 // Must start in another thread otherwise shutdown is interrupted
42 // TODO use an executor?
43 new Thread(() -> {
44 repositoryContext.getRepository().shutdown();
45 if (log.isDebugEnabled())
46 log.debug("Shut down repository " + pid
47 + (pidToCn.containsKey(pid) ? " (" + pidToCn.get(pid) + ")" : ""));
48 }, "Shutdown JCR repository " + pid).start();
49 } catch (Exception e) {
50 log.error("Error when shutting down Jackrabbit repository " + pid, e);
51 }
52 }
53 }
54
55 @Override
56 public String getName() {
57 return "Jackrabbit repository service factory";
58 }
59
60 @Override
61 public void updated(String pid, Dictionary<String, ?> properties) throws ConfigurationException {
62 if (repositories.containsKey(pid))
63 throw new IllegalArgumentException("Already a repository registered for " + pid);
64
65 if (properties == null)
66 return;
67
68 Object cn = properties.get(CmsConstants.CN);
69 if (cn != null)
70 for (String otherPid : pidToCn.keySet()) {
71 Object o = pidToCn.get(otherPid);
72 if (cn.equals(o)) {
73 RepositoryContext repositoryContext = repositories.remove(otherPid);
74 repositories.put(pid, repositoryContext);
75 if (log.isDebugEnabled())
76 log.debug("Ignoring update of Jackrabbit repository " + cn);
77 // FIXME perform a proper update (also of the OSGi service)
78 return;
79 }
80 }
81
82 try {
83 Object labeledUri = properties.get(RepoConf.labeledUri.name());
84 if (labeledUri == null) {
85 RepositoryBuilder repositoryBuilder = new RepositoryBuilder();
86 RepositoryContext repositoryContext = repositoryBuilder.createRepositoryContext(properties);
87 repositories.put(pid, repositoryContext);
88 Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
89 // props.put(ArgeoJcrConstants.JCR_REPOSITORY_URI,
90 // properties.get(RepoConf.labeledUri.name()));
91 if (cn != null) {
92 props.put(CmsConstants.CN, cn);
93 // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
94 pidToCn.put(pid, cn);
95 }
96 CmsJcrActivator.registerService(RepositoryContext.class, repositoryContext, props);
97 } else {
98 Object defaultWorkspace = properties.get(RepoConf.defaultWorkspace.name());
99 if (defaultWorkspace == null)
100 defaultWorkspace = RepoConf.defaultWorkspace.getDefault();
101 URI uri = new URI(labeledUri.toString());
102 // RepositoryFactory repositoryFactory = bc
103 // .getService(bc.getServiceReference(RepositoryFactory.class));
104 RepositoryFactory repositoryFactory = CmsJcrActivator.getService(RepositoryFactory.class);
105 Map<String, String> parameters = new HashMap<String, String>();
106 parameters.put(RepoConf.labeledUri.name(), uri.toString());
107 parameters.put(RepoConf.defaultWorkspace.name(), defaultWorkspace.toString());
108 Repository repository = repositoryFactory.getRepository(parameters);
109 // Repository repository = NodeUtils.getRepositoryByUri(repositoryFactory,
110 // uri.toString());
111 Dictionary<String, Object> props = LangUtils.dict(Constants.SERVICE_PID, pid);
112 props.put(RepoConf.labeledUri.name(),
113 new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null)
114 .toString());
115 if (cn != null) {
116 props.put(CmsConstants.CN, cn);
117 // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn);
118 pidToCn.put(pid, cn);
119 }
120 CmsJcrActivator.registerService(Repository.class, repository, props);
121
122 // home
123 if (cn.equals(CmsConstants.NODE_REPOSITORY)) {
124 Dictionary<String, Object> homeProps = LangUtils.dict(CmsConstants.CN, CmsConstants.EGO_REPOSITORY);
125 EgoRepository homeRepository = new EgoRepository(repository, true);
126 CmsJcrActivator.registerService(Repository.class, homeRepository, homeProps);
127 }
128 }
129 } catch (RepositoryException | URISyntaxException | IOException e) {
130 throw new IllegalStateException("Cannot create Jackrabbit repository " + pid, e);
131 }
132
133 }
134
135 @Override
136 public void deleted(String pid) {
137 RepositoryContext repositoryContext = repositories.remove(pid);
138 repositoryContext.getRepository().shutdown();
139 if (log.isDebugEnabled())
140 log.debug("Deleted repository " + pid);
141 }
142
143 }