1 package org
.argeo
.cms
.internal
.runtime
;
3 import java
.lang
.management
.ManagementFactory
;
4 import java
.util
.ArrayList
;
5 import java
.util
.HashMap
;
7 import java
.util
.Locale
;
10 import java
.util
.concurrent
.CompletableFuture
;
11 import java
.util
.concurrent
.ExecutionException
;
13 import javax
.security
.auth
.Subject
;
15 import org
.argeo
.api
.cms
.CmsContext
;
16 import org
.argeo
.api
.cms
.CmsDeployment
;
17 import org
.argeo
.api
.cms
.CmsEventBus
;
18 import org
.argeo
.api
.cms
.CmsLog
;
19 import org
.argeo
.api
.cms
.CmsSession
;
20 import org
.argeo
.api
.cms
.CmsSessionId
;
21 import org
.argeo
.api
.cms
.CmsState
;
22 import org
.argeo
.api
.uuid
.UuidFactory
;
23 import org
.argeo
.cms
.CmsDeployProperty
;
24 import org
.argeo
.cms
.internal
.auth
.CmsSessionImpl
;
25 import org
.ietf
.jgss
.GSSCredential
;
26 import org
.osgi
.service
.useradmin
.UserAdmin
;
28 public class CmsContextImpl
implements CmsContext
{
30 private final CmsLog log
= CmsLog
.getLog(getClass());
32 private static CompletableFuture
<CmsContextImpl
> instance
= new CompletableFuture
<CmsContextImpl
>();
33 // private static CmsContextImpl instance = null;
35 private CmsState cmsState
;
36 private CmsDeployment cmsDeployment
;
37 private UserAdmin userAdmin
;
38 private UuidFactory uuidFactory
;
39 private CmsEventBus cmsEventBus
;
40 // private ProvidedRepository contentRepository;
43 private Locale defaultLocale
;
44 private List
<Locale
> locales
= null;
46 private Long availableSince
;
49 private Map
<UUID
, CmsSessionImpl
> cmsSessionsByUuid
= new HashMap
<>();
50 private Map
<String
, CmsSessionImpl
> cmsSessionsByLocalId
= new HashMap
<>();
53 List
<String
> codes
= CmsStateImpl
.getDeployProperties(cmsState
, CmsDeployProperty
.LOCALE
);
54 locales
= getLocaleList(codes
);
55 if (locales
.size() == 0)
56 throw new IllegalStateException("At least one locale must be set");
57 defaultLocale
= locales
.get(0);
60 while (!checkReadiness()) {
63 } catch (InterruptedException e
) {
66 }, "Check readiness").start();
78 * Checks whether the deployment is available according to expectations, and
79 * mark it as available.
81 private boolean checkReadiness() {
84 if (cmsDeployment
== null)
87 if (((CmsDeploymentImpl
) cmsDeployment
).allExpectedServicesAvailable() && userAdmin
!= null) {
88 String data
= KernelUtils
.getFrameworkProp(KernelUtils
.OSGI_INSTANCE_AREA
);
89 String state
= KernelUtils
.getFrameworkProp(KernelUtils
.OSGI_CONFIGURATION_AREA
);
90 availableSince
= System
.currentTimeMillis();
91 long jvmUptime
= ManagementFactory
.getRuntimeMXBean().getUptime();
92 String jvmUptimeStr
= " in " + (jvmUptime
/ 1000) + "." + (jvmUptime
% 1000) + "s";
93 log
.info("## ARGEO CMS AVAILABLE" + (log
.isDebugEnabled() ? jvmUptimeStr
: "") + " ##");
94 if (log
.isDebugEnabled()) {
95 log
.debug("## state: " + state
);
97 log
.debug("## data: " + data
);
99 long begin
= cmsState
.getAvailableSince();
100 long initDuration
= System
.currentTimeMillis() - begin
;
101 if (log
.isTraceEnabled())
102 log
.trace("Kernel initialization took " + initDuration
+ "ms");
103 tributeToFreeSoftware(initDuration
);
108 // throw new IllegalStateException("Deployment is not available");
112 final private void tributeToFreeSoftware(long initDuration
) {
113 if (log
.isTraceEnabled()) {
114 long ms
= initDuration
/ 100;
115 log
.trace("Spend " + ms
+ "ms" + " reflecting on the progress brought to mankind" + " by Free Software...");
116 long beginNano
= System
.nanoTime();
119 } catch (InterruptedException e
) {
122 long durationNano
= System
.nanoTime() - beginNano
;
123 final double M
= 1000d
* 1000d
;
124 double sleepAccuracy
= ((double) durationNano
) / (ms
* M
);
125 log
.trace("Sleep accuracy: " + String
.format("%.2f", 100 - (sleepAccuracy
* 100 - 100)) + " %");
130 public void createWorkgroup(String dn
) {
131 // if (egoRepository == null)
132 // throw new CmsException("Ego repository is not available");
133 // // TODO add check that the group exists
134 // egoRepository.createWorkgroup(dn);
135 throw new UnsupportedOperationException();
138 /** Returns null if argument is null. */
139 private static List
<Locale
> getLocaleList(List
<String
> codes
) {
142 ArrayList
<Locale
> availableLocales
= new ArrayList
<Locale
>();
143 for (String code
: codes
) {
146 // variant not supported
147 int indexUnd
= code
.indexOf("_");
150 String language
= code
.substring(0, indexUnd
);
151 String country
= code
.substring(indexUnd
+ 1);
152 locale
= new Locale(language
, country
);
154 locale
= new Locale(code
);
156 availableLocales
.add(locale
);
158 return availableLocales
;
161 public void setCmsDeployment(CmsDeployment cmsDeployment
) {
162 this.cmsDeployment
= cmsDeployment
;
165 public void setCmsState(CmsState cmsState
) {
166 this.cmsState
= cmsState
;
169 public void setUserAdmin(UserAdmin userAdmin
) {
170 this.userAdmin
= userAdmin
;
173 public UuidFactory
getUuidFactory() {
177 public void setUuidFactory(UuidFactory uuidFactory
) {
178 this.uuidFactory
= uuidFactory
;
181 // public ProvidedRepository getContentRepository() {
182 // return contentRepository;
185 // public void setContentRepository(ProvidedRepository contentRepository) {
186 // this.contentRepository = contentRepository;
190 public Locale
getDefaultLocale() {
191 return defaultLocale
;
195 public UUID
timeUUID() {
196 return uuidFactory
.timeUUID();
200 public List
<Locale
> getLocales() {
205 public Long
getAvailableSince() {
206 return availableSince
;
209 public boolean isAvailable() {
210 return availableSince
!= null;
213 public CmsState
getCmsState() {
218 public CmsEventBus
getCmsEventBus() {
222 public void setCmsEventBus(CmsEventBus cmsEventBus
) {
223 this.cmsEventBus
= cmsEventBus
;
230 public static CmsContextImpl
getCmsContext() {
231 return getInstance();
234 /** Required by SPNEGO login module. */
235 public GSSCredential
getAcceptorCredentials() {
236 // TODO find a cleaner way
237 return ((CmsUserAdmin
) userAdmin
).getAcceptorCredentials();
240 private static void setInstance(CmsContextImpl cmsContextImpl
) {
241 // if (cmsContextImpl != null) {
242 // if (instance != null)
243 // throw new IllegalStateException("CMS Context is already set");
244 // instance = cmsContextImpl;
248 // CmsContextImpl.class.notifyAll();
250 if (cmsContextImpl
!= null) {
251 if (instance
.isDone())
252 throw new IllegalStateException("CMS Context is already set");
253 instance
.complete(cmsContextImpl
);
255 if (!instance
.isDone())
256 instance
.cancel(true);
257 instance
= new CompletableFuture
<CmsContextImpl
>();
261 private static CmsContextImpl
getInstance() {
262 // while (instance == null) {
264 // CmsContextImpl.class.wait();
265 // } catch (InterruptedException e) {
266 // throw new IllegalStateException("Cannot wait for CMS context instance", e);
272 return instance
.get();
273 } catch (InterruptedException
| ExecutionException e
) {
274 throw new IllegalStateException("Cannot retrieve CMS Context", e
);
278 public UserAdmin
getUserAdmin() {
287 public CmsSession
getCmsSession(Subject subject
) {
288 if (subject
.getPrivateCredentials(CmsSessionId
.class).isEmpty())
290 CmsSessionId cmsSessionId
= subject
.getPrivateCredentials(CmsSessionId
.class).iterator().next();
291 return getCmsSessionByUuid(cmsSessionId
.getUuid());
294 public void registerCmsSession(CmsSessionImpl cmsSession
) {
295 if (cmsSessionsByUuid
.containsKey(cmsSession
.getUuid())
296 || cmsSessionsByLocalId
.containsKey(cmsSession
.getLocalId()))
297 throw new IllegalStateException("CMS session " + cmsSession
+ " is already registered.");
298 cmsSessionsByUuid
.put(cmsSession
.getUuid(), cmsSession
);
299 cmsSessionsByLocalId
.put(cmsSession
.getLocalId(), cmsSession
);
302 public void unregisterCmsSession(CmsSessionImpl cmsSession
) {
303 if (!cmsSessionsByUuid
.containsKey(cmsSession
.getUuid())
304 || !cmsSessionsByLocalId
.containsKey(cmsSession
.getLocalId()))
305 throw new IllegalStateException("CMS session " + cmsSession
+ " is not registered.");
306 CmsSession removed
= cmsSessionsByUuid
.remove(cmsSession
.getUuid());
307 assert removed
== cmsSession
;
308 cmsSessionsByLocalId
.remove(cmsSession
.getLocalId());
312 * The {@link CmsSession} related to this UUID, or <code>null</null> if not
315 public CmsSessionImpl
getCmsSessionByUuid(UUID uuid
) {
316 return cmsSessionsByUuid
.get(uuid
);
320 * The {@link CmsSession} related to this local id, or <code>null</null> if not
323 public CmsSessionImpl
getCmsSessionByLocalId(String localId
) {
324 return cmsSessionsByLocalId
.get(localId
);