1 package org
.argeo
.cms
.internal
.kernel
;
3 import java
.lang
.management
.ManagementFactory
;
5 import java
.util
.HashMap
;
8 import javax
.jcr
.Repository
;
9 import javax
.jcr
.RepositoryFactory
;
11 import org
.apache
.commons
.logging
.Log
;
12 import org
.apache
.commons
.logging
.LogFactory
;
13 import org
.apache
.jackrabbit
.util
.TransientFileFactory
;
14 import org
.argeo
.ArgeoException
;
15 import org
.argeo
.cms
.CmsException
;
16 import org
.argeo
.jackrabbit
.OsgiJackrabbitRepositoryFactory
;
17 import org
.argeo
.jcr
.ArgeoJcrConstants
;
18 import org
.argeo
.security
.core
.InternalAuthentication
;
19 import org
.eclipse
.equinox
.http
.servlet
.ExtendedHttpService
;
20 import org
.osgi
.framework
.BundleContext
;
21 import org
.osgi
.framework
.ServiceEvent
;
22 import org
.osgi
.framework
.ServiceListener
;
23 import org
.osgi
.framework
.ServiceReference
;
24 import org
.osgi
.util
.tracker
.ServiceTracker
;
25 import org
.springframework
.security
.core
.context
.SecurityContextHolder
;
28 * Argeo CMS Kernel. Responsible for :
31 * <li>provisioning</li>
32 * <li>transaction</li>
34 * <li>local and remote file systems access</li>
38 final class Kernel
implements ServiceListener
{
39 private final static Log log
= LogFactory
.getLog(Kernel
.class);
41 private final BundleContext bundleContext
= Activator
.getBundleContext();
43 ThreadGroup threadGroup
= new ThreadGroup(Kernel
.class.getSimpleName());
45 OsgiJackrabbitRepositoryFactory repositoryFactory
;
46 NodeSecurity nodeSecurity
;
48 private KernelThread kernelThread
;
51 URL url
= getClass().getClassLoader().getResource(
52 KernelConstants
.JAAS_CONFIG
);
53 System
.setProperty("java.security.auth.login.config",
54 url
.toExternalForm());
56 ClassLoader currentContextCl
= Thread
.currentThread()
57 .getContextClassLoader();
58 Thread
.currentThread().setContextClassLoader(
59 Kernel
.class.getClassLoader());
60 long begin
= System
.currentTimeMillis();
61 InternalAuthentication initAuth
= new InternalAuthentication(
62 KernelConstants
.DEFAULT_SECURITY_KEY
);
63 SecurityContextHolder
.getContext().setAuthentication(initAuth
);
67 node
= new JackrabbitNode(bundleContext
);
69 // JCR repository factory
70 repositoryFactory
= new OsgiJackrabbitRepositoryFactory();
73 nodeSecurity
= new NodeSecurity(bundleContext
, node
);
76 ExtendedHttpService httpService
= waitForHttpService();
77 nodeHttp
= new NodeHttp(httpService
, node
, nodeSecurity
);
80 kernelThread
= new KernelThread(this);
81 kernelThread
.setContextClassLoader(Kernel
.class.getClassLoader());
84 // Publish services to OSGi
85 nodeSecurity
.publish();
86 node
.publish(repositoryFactory
);
87 bundleContext
.registerService(RepositoryFactory
.class,
88 repositoryFactory
, null);
90 bundleContext
.addServiceListener(Kernel
.this);
91 } catch (Exception e
) {
92 log
.error("Cannot initialize Argeo CMS", e
);
93 throw new ArgeoException("Cannot initialize", e
);
95 Thread
.currentThread().setContextClassLoader(currentContextCl
);
98 long jvmUptime
= ManagementFactory
.getRuntimeMXBean().getUptime();
99 log
.info("## ARGEO CMS UP in " + (jvmUptime
/ 1000) + "."
100 + (jvmUptime
% 1000) + "s ##");
101 long initDuration
= System
.currentTimeMillis() - begin
;
102 if (log
.isTraceEnabled())
103 log
.trace("Kernel initialization took " + initDuration
+ "ms");
104 directorsCut(initDuration
);
108 long begin
= System
.currentTimeMillis();
110 kernelThread
.destroyAndJoin();
112 if (nodeHttp
!= null)
114 if (nodeSecurity
!= null)
115 nodeSecurity
.destroy();
119 bundleContext
.removeServiceListener(this);
121 // Clean hanging threads from Jackrabbit
122 TransientFileFactory
.shutdown();
124 long duration
= System
.currentTimeMillis() - begin
;
125 log
.info("## ARGEO CMS DOWN in " + (duration
/ 1000) + "."
126 + (duration
% 1000) + "s ##");
130 public void serviceChanged(ServiceEvent event
) {
131 ServiceReference
<?
> sr
= event
.getServiceReference();
132 Object jcrRepoAlias
= sr
133 .getProperty(ArgeoJcrConstants
.JCR_REPOSITORY_ALIAS
);
134 if (jcrRepoAlias
!= null) {// JCR repository
135 String alias
= jcrRepoAlias
.toString();
136 Repository repository
= (Repository
) bundleContext
.getService(sr
);
137 Map
<String
, Object
> props
= new HashMap
<String
, Object
>();
138 for (String key
: sr
.getPropertyKeys())
139 props
.put(key
, sr
.getProperty(key
));
140 if (ServiceEvent
.REGISTERED
== event
.getType()) {
142 repositoryFactory
.register(repository
, props
);
143 nodeHttp
.registerRepositoryServlets(alias
, repository
);
144 } catch (Exception e
) {
145 throw new CmsException("Could not publish JCR repository "
148 } else if (ServiceEvent
.UNREGISTERING
== event
.getType()) {
149 repositoryFactory
.unregister(repository
, props
);
150 nodeHttp
.unregisterRepositoryServlets(alias
);
156 private ExtendedHttpService
waitForHttpService() {
157 final ServiceTracker
<ExtendedHttpService
, ExtendedHttpService
> st
= new ServiceTracker
<ExtendedHttpService
, ExtendedHttpService
>(
158 bundleContext
, ExtendedHttpService
.class, null);
160 ExtendedHttpService httpService
;
162 httpService
= st
.waitForService(1000);
163 } catch (InterruptedException e
) {
167 if (httpService
== null)
168 throw new CmsException("Could not find "
169 + ExtendedHttpService
.class + " service.");
173 final private static void directorsCut(long initDuration
) {
174 // final long ms = 128l + (long) (Math.random() * 128d);
175 long ms
= initDuration
/ 100;
176 log
.info("Spend " + ms
+ "ms"
177 + " reflecting on the progress brought to mankind"
178 + " by Free Software...");
179 long beginNano
= System
.nanoTime();
182 } catch (InterruptedException e
) {
185 long durationNano
= System
.nanoTime() - beginNano
;
186 final double M
= 1000d
* 1000d
;
187 double sleepAccuracy
= ((double) durationNano
) / (ms
* M
);
188 if (log
.isDebugEnabled())
189 log
.debug("Sleep accuracy: "
190 + String
.format("%.2f", 100 - (sleepAccuracy
* 100 - 100))