1 package org
.argeo
.cms
.internal
.runtime
;
3 import static java
.util
.Locale
.ENGLISH
;
5 import java
.lang
.management
.ManagementFactory
;
6 import java
.util
.ArrayList
;
7 import java
.util
.HashMap
;
9 import java
.util
.Locale
;
11 import java
.util
.UUID
;
12 import java
.util
.concurrent
.CompletableFuture
;
13 import java
.util
.concurrent
.ExecutionException
;
15 import javax
.security
.auth
.Subject
;
17 import org
.argeo
.api
.cms
.CmsConstants
;
18 import org
.argeo
.api
.cms
.CmsContext
;
19 import org
.argeo
.api
.cms
.CmsDeployment
;
20 import org
.argeo
.api
.cms
.CmsLog
;
21 import org
.argeo
.api
.cms
.CmsSession
;
22 import org
.argeo
.api
.cms
.CmsSessionId
;
23 import org
.argeo
.api
.cms
.CmsState
;
24 import org
.argeo
.api
.uuid
.UuidFactory
;
25 import org
.argeo
.cms
.CmsDeployProperty
;
26 import org
.argeo
.cms
.LocaleUtils
;
27 import org
.argeo
.cms
.internal
.auth
.CmsSessionImpl
;
28 import org
.ietf
.jgss
.GSSCredential
;
29 import org
.osgi
.service
.useradmin
.UserAdmin
;
31 public class CmsContextImpl
implements CmsContext
{
32 private final CmsLog log
= CmsLog
.getLog(getClass());
33 // private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
35 // private EgoRepository egoRepository;
36 private static CompletableFuture
<CmsContextImpl
> instance
= new CompletableFuture
<CmsContextImpl
>();
38 private CmsState cmsState
;
39 private CmsDeployment cmsDeployment
;
40 private UserAdmin userAdmin
;
41 private UuidFactory uuidFactory
;
42 // private ProvidedRepository contentRepository;
45 private Locale defaultLocale
;
46 private List
<Locale
> locales
= null;
48 private Long availableSince
;
51 private Map
<UUID
, CmsSessionImpl
> cmsSessionsByUuid
= new HashMap
<>();
52 private Map
<String
, CmsSessionImpl
> cmsSessionsByLocalId
= new HashMap
<>();
54 // public CmsContextImpl() {
59 List
<String
> codes
= CmsStateImpl
.getDeployProperties(cmsState
, CmsDeployProperty
.LOCALE
);
60 locales
= getLocaleList(codes
);
61 if (locales
.size() == 0)
62 throw new IllegalStateException("At least one locale must be set");
63 defaultLocale
= locales
.get(0);
64 // Object defaultLocaleValue = KernelUtils.getFrameworkProp(CmsConstants.I18N_DEFAULT_LOCALE);
65 // defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString())
66 // : new Locale(ENGLISH.getLanguage());
68 // new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
70 // public Repository addingService(ServiceReference<Repository> reference) {
71 // Object cn = reference.getProperty(NodeConstants.CN);
72 // if (cn != null && cn.equals(NodeConstants.EGO_REPOSITORY)) {
73 //// egoRepository = (EgoRepository) bc.getService(reference);
74 // if (log.isTraceEnabled())
75 // log.trace("Home repository is available");
77 // return super.addingService(reference);
81 // public void removedService(ServiceReference<Repository> reference, Repository service) {
82 // super.removedService(reference, service);
83 //// egoRepository = null;
98 * Checks whether the deployment is available according to expectations, and
99 * mark it as available.
101 private void checkReadiness() {
104 if (cmsDeployment
!= null && userAdmin
!= null) {
105 String data
= KernelUtils
.getFrameworkProp(KernelUtils
.OSGI_INSTANCE_AREA
);
106 String state
= KernelUtils
.getFrameworkProp(KernelUtils
.OSGI_CONFIGURATION_AREA
);
107 availableSince
= System
.currentTimeMillis();
108 long jvmUptime
= ManagementFactory
.getRuntimeMXBean().getUptime();
109 String jvmUptimeStr
= " in " + (jvmUptime
/ 1000) + "." + (jvmUptime
% 1000) + "s";
110 log
.info("## ARGEO CMS AVAILABLE" + (log
.isDebugEnabled() ? jvmUptimeStr
: "") + " ##");
111 if (log
.isDebugEnabled()) {
112 log
.debug("## state: " + state
);
114 log
.debug("## data: " + data
);
116 long begin
= cmsState
.getAvailableSince();
117 long initDuration
= System
.currentTimeMillis() - begin
;
118 if (log
.isTraceEnabled())
119 log
.trace("Kernel initialization took " + initDuration
+ "ms");
120 tributeToFreeSoftware(initDuration
);
122 throw new IllegalStateException("Deployment is not available");
126 final private void tributeToFreeSoftware(long initDuration
) {
127 if (log
.isTraceEnabled()) {
128 long ms
= initDuration
/ 100;
129 log
.trace("Spend " + ms
+ "ms" + " reflecting on the progress brought to mankind" + " by Free Software...");
130 long beginNano
= System
.nanoTime();
133 } catch (InterruptedException e
) {
136 long durationNano
= System
.nanoTime() - beginNano
;
137 final double M
= 1000d
* 1000d
;
138 double sleepAccuracy
= ((double) durationNano
) / (ms
* M
);
139 log
.trace("Sleep accuracy: " + String
.format("%.2f", 100 - (sleepAccuracy
* 100 - 100)) + " %");
144 public void createWorkgroup(String dn
) {
145 // if (egoRepository == null)
146 // throw new CmsException("Ego repository is not available");
147 // // TODO add check that the group exists
148 // egoRepository.createWorkgroup(dn);
149 throw new UnsupportedOperationException();
152 /** Returns null if argument is null. */
153 private static List
<Locale
> getLocaleList(List
<String
> codes
) {
156 ArrayList
<Locale
> availableLocales
= new ArrayList
<Locale
>();
157 for (String code
: codes
) {
160 // variant not supported
161 int indexUnd
= code
.indexOf("_");
164 String language
= code
.substring(0, indexUnd
);
165 String country
= code
.substring(indexUnd
+ 1);
166 locale
= new Locale(language
, country
);
168 locale
= new Locale(code
);
170 availableLocales
.add(locale
);
172 return availableLocales
;
175 public void setCmsDeployment(CmsDeployment cmsDeployment
) {
176 this.cmsDeployment
= cmsDeployment
;
179 public void setCmsState(CmsState cmsState
) {
180 this.cmsState
= cmsState
;
183 public void setUserAdmin(UserAdmin userAdmin
) {
184 this.userAdmin
= userAdmin
;
187 public UuidFactory
getUuidFactory() {
191 public void setUuidFactory(UuidFactory uuidFactory
) {
192 this.uuidFactory
= uuidFactory
;
195 // public ProvidedRepository getContentRepository() {
196 // return contentRepository;
199 // public void setContentRepository(ProvidedRepository contentRepository) {
200 // this.contentRepository = contentRepository;
204 public Locale
getDefaultLocale() {
205 return defaultLocale
;
209 public List
<Locale
> getLocales() {
214 public synchronized Long
getAvailableSince() {
215 return availableSince
;
218 public synchronized boolean isAvailable() {
219 return availableSince
!= null;
223 public CmsState
getCmsState() {
231 public synchronized static CmsContextImpl
getCmsContext() {
232 return getInstance();
235 // /** Required by USER login module. */
236 // public synchronized static UserAdmin getUserAdmin() {
237 // return getInstance().userAdmin;
240 /** Required by SPNEGO login module. */
242 public synchronized static GSSCredential
getAcceptorCredentials() {
243 // FIXME find a cleaner way
244 return ((CmsUserAdmin
) getInstance().userAdmin
).getAcceptorCredentials();
247 private synchronized static void setInstance(CmsContextImpl cmsContextImpl
) {
248 if (cmsContextImpl
!= null) {
249 if (instance
.isDone())
250 throw new IllegalStateException("CMS Context is already set");
251 instance
.complete(cmsContextImpl
);
253 instance
= new CompletableFuture
<CmsContextImpl
>();
257 private synchronized static CmsContextImpl
getInstance() {
259 return instance
.get();
260 } catch (InterruptedException
| ExecutionException e
) {
261 throw new IllegalStateException("Cannot retrieve CMS Context", e
);
265 public UserAdmin
getUserAdmin() {
274 public synchronized CmsSession
getCmsSession(Subject subject
) {
275 if (subject
.getPrivateCredentials(CmsSessionId
.class).isEmpty())
277 CmsSessionId cmsSessionId
= subject
.getPrivateCredentials(CmsSessionId
.class).iterator().next();
278 return getCmsSessionByUuid(cmsSessionId
.getUuid());
281 public synchronized void registerCmsSession(CmsSessionImpl cmsSession
) {
282 if (cmsSessionsByUuid
.containsKey(cmsSession
.getUuid())
283 || cmsSessionsByLocalId
.containsKey(cmsSession
.getLocalId()))
284 throw new IllegalStateException("CMS session " + cmsSession
+ " is already registered.");
285 cmsSessionsByUuid
.put(cmsSession
.getUuid(), cmsSession
);
286 cmsSessionsByLocalId
.put(cmsSession
.getLocalId(), cmsSession
);
289 public synchronized void unregisterCmsSession(CmsSessionImpl cmsSession
) {
290 if (!cmsSessionsByUuid
.containsKey(cmsSession
.getUuid())
291 || !cmsSessionsByLocalId
.containsKey(cmsSession
.getLocalId()))
292 throw new IllegalStateException("CMS session " + cmsSession
+ " is not registered.");
293 CmsSession removed
= cmsSessionsByUuid
.remove(cmsSession
.getUuid());
294 assert removed
== cmsSession
;
295 cmsSessionsByLocalId
.remove(cmsSession
.getLocalId());
299 * The {@link CmsSession} related to this UUID, or <code>null</null> if not
302 public synchronized CmsSessionImpl
getCmsSessionByUuid(UUID uuid
) {
303 return cmsSessionsByUuid
.get(uuid
);
307 * The {@link CmsSession} related to this local id, or <code>null</null> if not
310 public synchronized CmsSessionImpl
getCmsSessionByLocalId(String localId
) {
311 return cmsSessionsByLocalId
.get(localId
);