]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/internal/kernel/Kernel.java
Register JCR repositories with the repository factory
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / internal / kernel / Kernel.java
1 package org.argeo.cms.internal.kernel;
2
3 import java.lang.management.ManagementFactory;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import javax.jcr.Repository;
8 import javax.jcr.RepositoryFactory;
9
10 import org.apache.commons.logging.Log;
11 import org.apache.commons.logging.LogFactory;
12 import org.apache.jackrabbit.util.TransientFileFactory;
13 import org.argeo.ArgeoException;
14 import org.argeo.cms.CmsException;
15 import org.argeo.jackrabbit.OsgiJackrabbitRepositoryFactory;
16 import org.argeo.jcr.ArgeoJcrConstants;
17 import org.argeo.security.core.InternalAuthentication;
18 import org.eclipse.equinox.http.servlet.ExtendedHttpService;
19 import org.osgi.framework.BundleContext;
20 import org.osgi.framework.ServiceEvent;
21 import org.osgi.framework.ServiceListener;
22 import org.osgi.framework.ServiceReference;
23 import org.osgi.util.tracker.ServiceTracker;
24 import org.springframework.security.core.context.SecurityContextHolder;
25
26 /**
27 * Argeo CMS Kernel. Responsible for :
28 * <ul>
29 * <li>security</li>
30 * <li>provisioning</li>
31 * <li>transaction</li>
32 * <li>logging</li>
33 * <li>local and remote file systems access</li>
34 * <li>OS access</li>
35 * </ul>
36 */
37 final class Kernel implements ServiceListener {
38 private final static Log log = LogFactory.getLog(Kernel.class);
39
40 private final BundleContext bundleContext = Activator.getBundleContext();
41
42 private JackrabbitNode node;
43 private OsgiJackrabbitRepositoryFactory repositoryFactory;
44 private NodeSecurity nodeSecurity;
45 private NodeHttp nodeHttp;
46
47 void init() {
48 ClassLoader currentContextCl = Thread.currentThread()
49 .getContextClassLoader();
50 Thread.currentThread().setContextClassLoader(
51 Kernel.class.getClassLoader());
52 long begin = System.currentTimeMillis();
53 InternalAuthentication initAuth = new InternalAuthentication(
54 KernelConstants.DEFAULT_SECURITY_KEY);
55 SecurityContextHolder.getContext().setAuthentication(initAuth);
56
57 try {
58 // Jackrabbit node
59 node = new JackrabbitNode(bundleContext);
60
61 // JCR repository factory
62 repositoryFactory = new OsgiJackrabbitRepositoryFactory();
63
64 // Authentication
65 nodeSecurity = new NodeSecurity(bundleContext, node);
66
67 // Equinox dependency
68 ExtendedHttpService httpService = waitForHttpService();
69 nodeHttp = new NodeHttp(httpService, node, nodeSecurity);
70
71 // Publish services to OSGi
72 nodeSecurity.publish();
73 node.publish(repositoryFactory);
74 bundleContext.registerService(RepositoryFactory.class,
75 repositoryFactory, null);
76
77 bundleContext.addServiceListener(Kernel.this);
78 } catch (Exception e) {
79 log.error("Cannot initialize Argeo CMS", e);
80 throw new ArgeoException("Cannot initialize", e);
81 } finally {
82 Thread.currentThread().setContextClassLoader(currentContextCl);
83 }
84
85 long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
86 log.info("## ARGEO CMS UP in " + (jvmUptime / 1000) + "."
87 + (jvmUptime % 1000) + "s ##");
88 long initDuration = System.currentTimeMillis() - begin;
89 if (log.isTraceEnabled())
90 log.trace("Kernel initialization took " + initDuration + "ms");
91 directorsCut(initDuration);
92 }
93
94 void destroy() {
95 long begin = System.currentTimeMillis();
96
97 if (nodeHttp != null)
98 nodeHttp.destroy();
99 if (nodeSecurity != null)
100 nodeSecurity.destroy();
101 if (node != null)
102 node.destroy();
103
104 bundleContext.removeServiceListener(this);
105
106 // Clean hanging threads from Jackrabbit
107 TransientFileFactory.shutdown();
108
109 long duration = System.currentTimeMillis() - begin;
110 log.info("## ARGEO CMS DOWN in " + (duration / 1000) + "."
111 + (duration % 1000) + "s ##");
112 }
113
114 @Override
115 public void serviceChanged(ServiceEvent event) {
116 ServiceReference<?> sr = event.getServiceReference();
117 Object jcrRepoAlias = sr
118 .getProperty(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
119 if (jcrRepoAlias != null) {// JCR repository
120 String alias = jcrRepoAlias.toString();
121 Repository repository = (Repository) bundleContext.getService(sr);
122 Map<String, Object> props = new HashMap<String, Object>();
123 for (String key : sr.getPropertyKeys())
124 props.put(key, sr.getProperty(key));
125 if (ServiceEvent.REGISTERED == event.getType()) {
126 try {
127 repositoryFactory.register(repository, props);
128 nodeHttp.registerRepositoryServlets(alias, repository);
129 } catch (Exception e) {
130 throw new CmsException("Could not publish JCR repository "
131 + alias, e);
132 }
133 } else if (ServiceEvent.UNREGISTERING == event.getType()) {
134 repositoryFactory.unregister(repository, props);
135 nodeHttp.unregisterRepositoryServlets(alias);
136 }
137 }
138
139 }
140
141 private ExtendedHttpService waitForHttpService() {
142 final ServiceTracker<ExtendedHttpService, ExtendedHttpService> st = new ServiceTracker<ExtendedHttpService, ExtendedHttpService>(
143 bundleContext, ExtendedHttpService.class, null);
144 st.open();
145 ExtendedHttpService httpService;
146 try {
147 httpService = st.waitForService(1000);
148 } catch (InterruptedException e) {
149 httpService = null;
150 }
151
152 if (httpService == null)
153 throw new CmsException("Could not find "
154 + ExtendedHttpService.class + " service.");
155 return httpService;
156 }
157
158 final private static void directorsCut(long initDuration) {
159 // final long ms = 128l + (long) (Math.random() * 128d);
160 long ms = initDuration / 100;
161 log.info("Spend " + ms + "ms"
162 + " reflecting on the progress brought to mankind"
163 + " by Free Software...");
164 long beginNano = System.nanoTime();
165 try {
166 Thread.sleep(ms, 0);
167 } catch (InterruptedException e) {
168 // silent
169 }
170 long durationNano = System.nanoTime() - beginNano;
171 final double M = 1000d * 1000d;
172 double sleepAccuracy = ((double) durationNano) / (ms * M);
173 if (log.isDebugEnabled())
174 log.debug("Sleep accuracy: "
175 + String.format("%.2f", 100 - (sleepAccuracy * 100 - 100))
176 + " %");
177 }
178 }