]> git.argeo.org Git - gpl/argeo-suite.git/blob - swt/org.argeo.app.ui/src/org/argeo/app/ui/SuiteApp.java
Merge remote-tracking branch 'origin/unstable' into merge-to-testing
[gpl/argeo-suite.git] / swt / org.argeo.app.ui / src / org / argeo / app / ui / SuiteApp.java
1 package org.argeo.app.ui;
2
3 import static org.argeo.api.cms.ux.CmsView.CMS_VIEW_UID_PROPERTY;
4
5 import java.util.Collections;
6 import java.util.HashMap;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Locale;
10 import java.util.Map;
11 import java.util.Objects;
12 import java.util.Set;
13 import java.util.TreeMap;
14 import java.util.TreeSet;
15
16 import javax.jcr.Node;
17 import javax.jcr.RepositoryException;
18 import javax.jcr.nodetype.NodeType;
19 import javax.xml.namespace.QName;
20
21 import org.argeo.api.acr.Content;
22 import org.argeo.api.acr.ContentRepository;
23 import org.argeo.api.acr.spi.ProvidedSession;
24 import org.argeo.api.cms.CmsConstants;
25 import org.argeo.api.cms.CmsEventSubscriber;
26 import org.argeo.api.cms.CmsLog;
27 import org.argeo.api.cms.CmsSession;
28 import org.argeo.api.cms.ux.CmsTheme;
29 import org.argeo.api.cms.ux.CmsUi;
30 import org.argeo.api.cms.ux.CmsView;
31 import org.argeo.app.api.EntityConstants;
32 import org.argeo.app.api.EntityNames;
33 import org.argeo.app.api.EntityType;
34 import org.argeo.app.api.RankedObject;
35 import org.argeo.cms.AbstractCmsApp;
36 import org.argeo.cms.CmsUserManager;
37 import org.argeo.cms.LocaleUtils;
38 import org.argeo.cms.Localized;
39 import org.argeo.cms.acr.ContentUtils;
40 import org.argeo.cms.jcr.CmsJcrUtils;
41 import org.argeo.cms.jcr.acr.JcrContent;
42 import org.argeo.cms.swt.CmsSwtUtils;
43 import org.argeo.cms.swt.acr.SwtUiProvider;
44 import org.argeo.cms.swt.dialogs.CmsFeedback;
45 import org.argeo.cms.ux.CmsUxUtils;
46 import org.argeo.eclipse.ui.specific.UiContext;
47 import org.argeo.jcr.JcrException;
48 import org.argeo.util.LangUtils;
49 import org.eclipse.swt.SWT;
50 import org.eclipse.swt.widgets.Composite;
51 import org.osgi.framework.Constants;
52 import org.osgi.service.useradmin.User;
53
54 /** The Argeo Suite App. */
55 public class SuiteApp extends AbstractCmsApp implements CmsEventSubscriber {
56 private final static CmsLog log = CmsLog.getLog(SuiteApp.class);
57
58 public final static String PUBLIC_BASE_PATH_PROPERTY = "publicBasePath";
59 public final static String DEFAULT_UI_NAME_PROPERTY = "defaultUiName";
60 public final static String DEFAULT_THEME_ID_PROPERTY = "defaultThemeId";
61 public final static String DEFAULT_LAYER_PROPERTY = "defaultLayer";
62 private final static String LOGIN = "login";
63 private final static String HOME_STATE = "~";
64
65 private String publicBasePath = null;
66
67 private String pidPrefix;
68 private String headerPid;
69 private String footerPid;
70 private String leadPanePid;
71 private String adminLeadPanePid;
72 private String loginScreenPid;
73
74 private String defaultUiName = "app";
75 private String adminUiName = "admin";
76
77 // FIXME such default names make refactoring more dangerous
78 @Deprecated
79 private String defaultLayerPid = "argeo.suite.ui.dashboardLayer";
80 @Deprecated
81 private String defaultThemeId = "org.argeo.app.theme.default";
82
83 // TODO use QName as key for byType
84 private Map<String, RankedObject<SwtUiProvider>> uiProvidersByPid = Collections.synchronizedMap(new HashMap<>());
85 private Map<String, RankedObject<SwtUiProvider>> uiProvidersByType = Collections.synchronizedMap(new HashMap<>());
86 private Map<String, RankedObject<SuiteLayer>> layersByPid = Collections.synchronizedSortedMap(new TreeMap<>());
87 private Map<String, RankedObject<SuiteLayer>> layersByType = Collections.synchronizedSortedMap(new TreeMap<>());
88
89 private CmsUserManager cmsUserManager;
90
91 // TODO make more optimal or via CmsSession/CmsView
92 private Map<String, SuiteUi> managedUis = new HashMap<>();
93
94 // ACR
95 private ContentRepository contentRepository;
96 // private JcrContentProvider jcrContentProvider;
97
98 // JCR
99 // private Repository repository;
100
101 public void init(Map<String, Object> properties) {
102 for (SuiteEvent event : SuiteEvent.values()) {
103 getCmsContext().getCmsEventBus().addEventSubscriber(event.topic(), this);
104 }
105
106 if (log.isDebugEnabled())
107 log.info("Argeo Suite App started");
108
109 if (properties.containsKey(DEFAULT_UI_NAME_PROPERTY))
110 defaultUiName = LangUtils.get(properties, DEFAULT_UI_NAME_PROPERTY);
111 if (properties.containsKey(DEFAULT_THEME_ID_PROPERTY))
112 defaultThemeId = LangUtils.get(properties, DEFAULT_THEME_ID_PROPERTY);
113 if (properties.containsKey(DEFAULT_LAYER_PROPERTY))
114 defaultLayerPid = LangUtils.get(properties, DEFAULT_LAYER_PROPERTY);
115 publicBasePath = LangUtils.get(properties, PUBLIC_BASE_PATH_PROPERTY);
116
117 if (properties.containsKey(Constants.SERVICE_PID)) {
118 String servicePid = properties.get(Constants.SERVICE_PID).toString();
119 if (servicePid.endsWith(".app")) {
120 pidPrefix = servicePid.substring(0, servicePid.length() - "app".length());
121 }
122 }
123
124 if (pidPrefix == null)
125 throw new IllegalArgumentException("PID prefix must be set.");
126
127 headerPid = pidPrefix + "header";
128 footerPid = pidPrefix + "footer";
129 leadPanePid = pidPrefix + "leadPane";
130 adminLeadPanePid = pidPrefix + "adminLeadPane";
131 loginScreenPid = pidPrefix + "loginScreen";
132 }
133
134 public void destroy(Map<String, Object> properties) {
135 for (SuiteUi ui : managedUis.values())
136 if (!ui.isDisposed()) {
137 ui.getDisplay().syncExec(() -> ui.dispose());
138 }
139 if (log.isDebugEnabled())
140 log.info("Argeo Suite App stopped");
141
142 }
143
144 @Override
145 public Set<String> getUiNames() {
146 HashSet<String> uiNames = new HashSet<>();
147 uiNames.add(defaultUiName);
148 uiNames.add(adminUiName);
149 return uiNames;
150 }
151
152 @Override
153 public CmsUi initUi(Object parent) {
154 Composite uiParent = (Composite) parent;
155 String uiName = uiParent.getData(UI_NAME_PROPERTY) != null ? uiParent.getData(UI_NAME_PROPERTY).toString()
156 : null;
157 CmsView cmsView = CmsSwtUtils.getCmsView(uiParent);
158 if (cmsView == null)
159 throw new IllegalStateException("No CMS view is registered.");
160 CmsTheme theme = getTheme(uiName);
161 if (theme != null)
162 CmsSwtUtils.registerCmsTheme(uiParent.getShell(), theme);
163 SuiteUi argeoSuiteUi = new SuiteUi(uiParent, SWT.INHERIT_DEFAULT);
164 String uid = cmsView.getUid();
165 managedUis.put(uid, argeoSuiteUi);
166 argeoSuiteUi.addDisposeListener((e) -> {
167 managedUis.remove(uid);
168 if (log.isDebugEnabled())
169 log.debug("Suite UI " + uid + " has been disposed.");
170 });
171 return argeoSuiteUi;
172 }
173
174 @Override
175 public String getThemeId(String uiName) {
176 String themeId = System.getProperty("org.argeo.app.theme.default");
177 if (themeId != null)
178 return themeId;
179 return defaultThemeId;
180 }
181
182 @Override
183 public void refreshUi(CmsUi cmsUi, String state) {
184 try {
185 Content context = null;
186 SuiteUi ui = (SuiteUi) cmsUi;
187
188 String uiName = Objects.toString(ui.getParent().getData(UI_NAME_PROPERTY), null);
189 if (uiName == null)
190 throw new IllegalStateException("UI name should not be null");
191 CmsView cmsView = CmsSwtUtils.getCmsView(ui);
192
193 ProvidedSession contentSession = (ProvidedSession) CmsUxUtils.getContentSession(contentRepository, cmsView);
194
195 SwtUiProvider headerUiProvider = findUiProvider(headerPid);
196 SwtUiProvider footerUiProvider = findUiProvider(footerPid);
197 SwtUiProvider leadPaneUiProvider;
198 if (adminUiName.equals(uiName)) {
199 leadPaneUiProvider = findUiProvider(adminLeadPanePid);
200 } else {
201 leadPaneUiProvider = findUiProvider(leadPanePid);
202 }
203
204 Localized appTitle = null;
205 if (headerUiProvider instanceof DefaultHeader) {
206 appTitle = ((DefaultHeader) headerUiProvider).getTitle();
207 }
208 ui.setTitle(appTitle);
209
210 if (cmsView.isAnonymous() && publicBasePath == null) {// internal app, must login
211 ui.logout();
212 ui.setLoginScreen(true);
213 if (headerUiProvider != null)
214 refreshPart(headerUiProvider, ui.getHeader(), context);
215 ui.refreshBelowHeader(false);
216 refreshPart(findUiProvider(loginScreenPid), ui.getBelowHeader(), context);
217 if (footerUiProvider != null)
218 refreshPart(footerUiProvider, ui.getFooter(), context);
219 ui.layout(true, true);
220 setState(ui, LOGIN);
221 } else {
222 if (LOGIN.equals(state))
223 state = null;
224 if (ui.isLoginScreen()) {
225 // if (state == null)
226 // state = ui.getPostLoginState();
227 ui.setLoginScreen(false);
228 // ui.setPostLoginState(null);
229 }
230 CmsSession cmsSession = cmsView.getCmsSession();
231 if (ui.getUserDirNode() == null) {
232 // FIXME NPE on CMSSession when logging in from anonymous
233 if (cmsSession == null || cmsView.isAnonymous()) {
234 assert publicBasePath != null;
235 Content userDir = contentSession
236 .get(ContentUtils.SLASH + CmsConstants.SYS_WORKSPACE + publicBasePath);
237 ui.setUserDir(userDir);
238 // ui.initSessions(getRepository(), publicBasePath);
239 } else {
240 // Session adminSession = null;
241 // try {
242 // adminSession = CmsJcrUtils.openDataAdminSession(getRepository(), null);
243 // Node userDirNode = SuiteUtils.getOrCreateCmsSessionNode(adminSession, cmsSession);
244 // Content userDir = contentSession.get(CmsConstants.SYS_WORKSPACE + userDirNode.getPath());
245 // ui.setUserDir(userDir);
246 //// ui.initSessions(getRepository(), userDirNode.getPath());
247 // } finally {
248 // Jcr.logout(adminSession);
249 // }
250 Content userDir = contentSession.getSessionRunDir();
251 ui.setUserDir(userDir);
252 }
253 }
254 initLocale(cmsSession);
255 context = stateToNode(ui, state);
256 if (context == null)
257 context = ui.getUserDirNode();
258
259 if (headerUiProvider != null)
260 refreshPart(headerUiProvider, ui.getHeader(), context);
261 ui.refreshBelowHeader(true);
262 for (String key : layersByPid.keySet()) {
263 SuiteLayer layer = layersByPid.get(key).get();
264 ui.addLayer(key, layer);
265 }
266
267 if (leadPaneUiProvider != null)
268 refreshPart(leadPaneUiProvider, ui.getLeadPane(), context);
269 if (footerUiProvider != null)
270 refreshPart(footerUiProvider, ui.getFooter(), context);
271 ui.layout(true, true);
272 setState(ui, state != null ? state : defaultLayerPid);
273 }
274 } catch (Exception e) {
275 CmsFeedback.error("Unexpected exception", e);
276 }
277 }
278
279 private void initLocale(CmsSession cmsSession) {
280 if (cmsSession == null)
281 return;
282 Locale locale = cmsSession.getLocale();
283 UiContext.setLocale(locale);
284 LocaleUtils.setThreadLocale(locale);
285
286 }
287
288 private void refreshPart(SwtUiProvider uiProvider, Composite part, Content context) {
289 CmsSwtUtils.clear(part);
290 uiProvider.createUiPart(part, context);
291 }
292
293 private SwtUiProvider findUiProvider(String pid) {
294 if (!uiProvidersByPid.containsKey(pid))
295 return null;
296 return uiProvidersByPid.get(pid).get();
297 }
298
299 private SuiteLayer findLayer(String pid) {
300 if (!layersByPid.containsKey(pid))
301 return null;
302 return layersByPid.get(pid).get();
303 }
304
305 private <T> T findByType(Map<String, RankedObject<T>> byType, Content content) {
306 if (content == null)
307 throw new IllegalArgumentException("A node should be provided");
308
309 if (content instanceof JcrContent) {
310 Node context = ((JcrContent) content).getJcrNode();
311 try {
312 // mixins
313 Set<String> types = new TreeSet<>();
314 for (NodeType mixinType : context.getMixinNodeTypes()) {
315 String mixinTypeName = mixinType.getName();
316 if (byType.containsKey(mixinTypeName)) {
317 types.add(mixinTypeName);
318 }
319 for (NodeType superType : mixinType.getDeclaredSupertypes()) {
320 if (byType.containsKey(superType.getName())) {
321 types.add(superType.getName());
322 }
323 }
324 }
325 // primary node type
326 NodeType primaryType = context.getPrimaryNodeType();
327 String primaryTypeName = primaryType.getName();
328 if (byType.containsKey(primaryTypeName)) {
329 types.add(primaryTypeName);
330 }
331 for (NodeType superType : primaryType.getDeclaredSupertypes()) {
332 if (byType.containsKey(superType.getName())) {
333 types.add(superType.getName());
334 }
335 }
336 // entity type
337 if (context.isNodeType(EntityType.entity.get())) {
338 if (context.hasProperty(EntityNames.ENTITY_TYPE)) {
339 String entityTypeName = context.getProperty(EntityNames.ENTITY_TYPE).getString();
340 if (byType.containsKey(entityTypeName)) {
341 types.add(entityTypeName);
342 }
343 }
344 }
345
346 // if (context.getPath().equals("/")) {// root node
347 // types.add("nt:folder");
348 // }
349 if (CmsJcrUtils.isUserHome(context) && byType.containsKey("nt:folder")) {// home node
350 types.add("nt:folder");
351 }
352
353 if (types.size() == 0)
354 throw new IllegalArgumentException(
355 "No type found for " + context + " (" + listTypes(context) + ")");
356 String type = types.iterator().next();
357 if (!byType.containsKey(type))
358 throw new IllegalArgumentException("No component found for " + context + " with type " + type);
359 return byType.get(type).get();
360 } catch (RepositoryException e) {
361 throw new IllegalStateException(e);
362 }
363
364 } else {
365
366 List<QName> objectClasses = content.getContentClasses();
367 Set<String> types = new TreeSet<>();
368 for (QName cc : objectClasses) {
369 String type = cc.getPrefix() + ":" + cc.getLocalPart();
370 if (byType.containsKey(type))
371 types.add(type);
372 }
373 if (types.size() == 0) {
374 throw new IllegalArgumentException("No type found for " + content + " (" + objectClasses + ")");
375 }
376 String type = types.iterator().next();
377 if (!byType.containsKey(type))
378 throw new IllegalArgumentException("No component found for " + content + " with type " + type);
379 return byType.get(type).get();
380 // throw new UnsupportedOperationException("Content " +
381 // content.getClass().getName() + " is not supported.");
382 }
383 }
384
385 private static String listTypes(Node context) {
386 try {
387 StringBuilder sb = new StringBuilder();
388 sb.append(context.getPrimaryNodeType().getName());
389 for (NodeType superType : context.getPrimaryNodeType().getDeclaredSupertypes()) {
390 sb.append(' ');
391 sb.append(superType.getName());
392 }
393
394 for (NodeType nodeType : context.getMixinNodeTypes()) {
395 sb.append(' ');
396 sb.append(nodeType.getName());
397 if (nodeType.getName().equals(EntityType.local.get()))
398 sb.append('/').append(context.getProperty(EntityNames.ENTITY_TYPE).getString());
399 for (NodeType superType : nodeType.getDeclaredSupertypes()) {
400 sb.append(' ');
401 sb.append(superType.getName());
402 }
403 }
404 return sb.toString();
405 } catch (RepositoryException e) {
406 throw new JcrException(e);
407 }
408 }
409
410 @Override
411 public void setState(CmsUi cmsUi, String state) {
412 if (state == null)
413 return;
414 if (!state.startsWith("/")) {
415 if (cmsUi instanceof SuiteUi) {
416 SuiteUi ui = (SuiteUi) cmsUi;
417 if (LOGIN.equals(state)) {
418 String appTitle = "";
419 if (ui.getTitle() != null)
420 appTitle = ui.getTitle().lead();
421 ui.getCmsView().stateChanged(state, appTitle);
422 return;
423 }
424 Map<String, Object> properties = new HashMap<>();
425 String layerId = HOME_STATE.equals(state) ? defaultLayerPid : state;
426 properties.put(SuiteEvent.LAYER, layerId);
427 properties.put(SuiteEvent.NODE_PATH, HOME_STATE);
428 ui.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), properties);
429 }
430 return;
431 }
432 SuiteUi suiteUi = (SuiteUi) cmsUi;
433 if (suiteUi.isLoginScreen()) {
434 // suiteUi.setPostLoginState(state);
435 return;
436 }
437
438 Content node = stateToNode(suiteUi, state);
439 if (node == null) {
440 suiteUi.getCmsView().navigateTo(HOME_STATE);
441 } else {
442 suiteUi.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), SuiteEvent.eventProperties(node));
443 suiteUi.getCmsView().sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(node));
444 }
445 }
446
447 // TODO move it to an internal package?
448 static String nodeToState(Content node) {
449 return node.getPath();
450 }
451
452 private Content stateToNode(SuiteUi suiteUi, String state) {
453 if (suiteUi == null)
454 return null;
455 if (state == null || !state.startsWith("/"))
456 return null;
457
458 String path = state;
459 // String path = state.substring(1);
460 // String workspace;
461 // if (path.equals("")) {
462 // workspace = null;
463 // path = "/";
464 // } else {
465 // int index = path.indexOf('/');
466 // if (index == 0) {
467 // log.error("Cannot interpret " + state);
468 //// cmsView.navigateTo("~");
469 // return null;
470 // } else if (index > 0) {
471 // workspace = path.substring(0, index);
472 // path = path.substring(index);
473 // } else {// index<0, assuming root node
474 // workspace = path;
475 // path = "/";
476 // }
477 // }
478
479 ProvidedSession contentSession = (ProvidedSession) CmsUxUtils.getContentSession(contentRepository,
480 suiteUi.getCmsView());
481 return contentSession.get(path);
482 // Session session = jcrContentProvider.getJcrSession(contentSession, workspace);
483 //// Session session = suiteUi.getSession(workspace);
484 // if (session == null)
485 // return null;
486 // Node node = Jcr.getNode(session, path);
487 // return node;
488 }
489
490 /*
491 * Events management
492 */
493
494 @Override
495 public void onEvent(String topic, Map<String, Object> event) {
496
497 // Specific UI related events
498 SuiteUi ui = getRelatedUi(event);
499 if (ui == null)
500 return;
501 ui.getCmsView().runAs(() -> {
502 try {
503 String appTitle = "";
504 if (ui.getTitle() != null)
505 appTitle = ui.getTitle().lead() + " - ";
506
507 // String currentLayerId = ui.getCurrentLayerId();
508 // SuiteLayer currentLayer = currentLayerId != null ? layersByPid.get(currentLayerId).get() : null;
509 if (SuiteUiUtils.isTopic(topic, SuiteEvent.refreshPart)) {
510 Content node = getNode(ui, event);
511 if (node == null)
512 return;
513 SwtUiProvider uiProvider = findByType(uiProvidersByType, node);
514 SuiteLayer layer = findByType(layersByType, node);
515 ui.switchToLayer(layer, node);
516 layer.view(uiProvider, ui.getCurrentWorkArea(), node);
517 ui.getCmsView().stateChanged(nodeToState(node), appTitle + CmsUxUtils.getTitle(node));
518 } else if (SuiteUiUtils.isTopic(topic, SuiteEvent.openNewPart)) {
519 Content node = getNode(ui, event);
520 if (node == null)
521 return;
522 SwtUiProvider uiProvider = findByType(uiProvidersByType, node);
523 SuiteLayer layer = findByType(layersByType, node);
524 ui.switchToLayer(layer, node);
525 layer.open(uiProvider, ui.getCurrentWorkArea(), node);
526 ui.getCmsView().stateChanged(nodeToState(node), appTitle + CmsUxUtils.getTitle(node));
527 } else if (SuiteUiUtils.isTopic(topic, SuiteEvent.switchLayer)) {
528 String layerId = get(event, SuiteEvent.LAYER);
529 if (layerId != null) {
530 // ui.switchToLayer(layerId, ui.getUserDir());
531 SuiteLayer suiteLayer = findLayer(layerId);
532 if (suiteLayer == null)
533 throw new IllegalArgumentException("No layer '" + layerId + "' available.");
534 Localized layerTitle = suiteLayer.getTitle();
535 // FIXME make sure we don't rebuild the work area twice
536 Composite workArea = ui.switchToLayer(layerId, ui.getUserDirNode());
537 String title = null;
538 if (layerTitle != null)
539 title = layerTitle.lead();
540 Content nodeFromState = getNode(ui, event);
541 if (nodeFromState != null && nodeFromState.getPath().equals(ui.getUserDirNode().getPath())) {
542 // default layer view is forced
543 String state = defaultLayerPid.equals(layerId) ? "~" : layerId;
544 ui.getCmsView().stateChanged(state, appTitle + title);
545 suiteLayer.view(null, workArea, nodeFromState);
546 } else {
547 Content layerCurrentContext = suiteLayer.getCurrentContext(workArea);
548 if (layerCurrentContext != null) {
549 // layer was already showing a context so we set the state to it
550 ui.getCmsView().stateChanged(nodeToState(layerCurrentContext),
551 appTitle + CmsUxUtils.getTitle(layerCurrentContext));
552 } else {
553 // no context was shown
554 ui.getCmsView().stateChanged(layerId, appTitle + title);
555 }
556 }
557 } else {
558 Content node = getNode(ui, event);
559 if (node != null) {
560 SuiteLayer layer = findByType(layersByType, node);
561 ui.switchToLayer(layer, node);
562 }
563 }
564 }
565 } catch (Exception e) {
566 CmsFeedback.error("Cannot handle event " + topic + " " + event, e);
567 // log.error("Cannot handle event " + event, e);
568 }
569 });
570 }
571
572 private Content getNode(SuiteUi ui, Map<String, Object> event) {
573 ProvidedSession contentSession = (ProvidedSession) CmsUxUtils.getContentSession(contentRepository,
574 ui.getCmsView());
575
576 String path = get(event, SuiteEvent.CONTENT_PATH);
577
578 // String nodePath = get(event, SuiteEvent.NODE_PATH);
579 if (path != null && path.equals(HOME_STATE))
580 return ui.getUserDir();
581 // String workspace = get(event, SuiteEvent.WORKSPACE);
582
583 // Session session = jcrContentProvider.getJcrSession(contentSession, workspace);
584 //// Session session = ui.getSession(workspace);
585 Content node;
586 if (path == null) {
587 // look for a user
588 String username = get(event, SuiteEvent.USERNAME);
589 if (username == null)
590 return null;
591 User user = cmsUserManager.getUser(username);
592 if (user == null)
593 return null;
594 node = ContentUtils.roleToContent(cmsUserManager, contentSession, user);
595 // LdapName userDn;
596 // try {
597 // userDn = new LdapName(user.getName());
598 // } catch (InvalidNameException e) {
599 // throw new IllegalArgumentException("Badly formatted username", e);
600 // }
601 // String userNodePath = SuiteUtils.getUserNodePath(userDn);
602 // FIXME deal with home path
603 // return null;
604 // if (Jcr.itemExists(session, userNodePath))
605 // node = Jcr.getNode(session, userNodePath);
606 // else {
607 // Session adminSession = null;
608 // try {
609 // adminSession = CmsJcrUtils.openDataAdminSession(getRepository(), workspace);
610 // SuiteUtils.getOrCreateUserNode(adminSession, userDn);
611 // } finally {
612 // Jcr.logout(adminSession);
613 // }
614 // node = Jcr.getNode(session, userNodePath);
615 // }
616 } else {
617 node = contentSession.get(path);
618 }
619 return node;
620 }
621
622 private SuiteUi getRelatedUi(Map<String, Object> eventProperties) {
623 return managedUis.get(get(eventProperties, CMS_VIEW_UID_PROPERTY));
624 }
625
626 public static String get(Map<String, Object> eventProperties, String key) {
627 Object value = eventProperties.get(key);
628 if (value == null)
629 return null;
630 // throw new IllegalArgumentException("Property " + key + " must be set");
631 return value.toString();
632
633 }
634
635 /*
636 * Dependency injection.
637 */
638
639 public void addUiProvider(SwtUiProvider uiProvider, Map<String, Object> properties) {
640 if (properties.containsKey(Constants.SERVICE_PID)) {
641 String pid = (String) properties.get(Constants.SERVICE_PID);
642 RankedObject.putIfHigherRank(uiProvidersByPid, pid, uiProvider, properties);
643 }
644 if (properties.containsKey(EntityConstants.TYPE)) {
645 List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
646 for (String type : types) {
647 RankedObject.putIfHigherRank(uiProvidersByType, type, uiProvider, properties);
648 }
649 }
650 }
651
652 public void removeUiProvider(SwtUiProvider uiProvider, Map<String, Object> properties) {
653 if (properties.containsKey(Constants.SERVICE_PID)) {
654 String pid = (String) properties.get(Constants.SERVICE_PID);
655 if (uiProvidersByPid.containsKey(pid)) {
656 if (uiProvidersByPid.get(pid).equals(new RankedObject<SwtUiProvider>(uiProvider, properties))) {
657 uiProvidersByPid.remove(pid);
658 }
659 }
660 }
661 if (properties.containsKey(EntityConstants.TYPE)) {
662 List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
663 for (String type : types) {
664 if (uiProvidersByType.containsKey(type)) {
665 if (uiProvidersByType.get(type).equals(new RankedObject<SwtUiProvider>(uiProvider, properties))) {
666 uiProvidersByType.remove(type);
667 }
668 }
669 }
670 }
671 }
672
673 // public void addLayer(SuiteLayer layer, Map<String, Object> properties) {
674 // if (!properties.containsKey(Constants.SERVICE_PID))
675 // throw new IllegalArgumentException("A layer must have an ID");
676 // String pid = (String) properties.get(Constants.SERVICE_PID);
677 // List<String> types = properties.containsKey(EntityConstants.TYPE)
678 // ? LangUtils.toStringList(properties.get(EntityConstants.TYPE))
679 // : new ArrayList<>();
680 // if (types.isEmpty()) {
681 // RankedObject.putIfHigherRank(layersByPid, pid, layer, properties);
682 // } else {
683 // if (layersByPid.containsKey(pid)) {
684 // RankedObject<SuiteLayer> current = layersByPid.get(pid);
685 // List<String> currentTypes = current.getProperties().containsKey(EntityConstants.TYPE)
686 // ? LangUtils.toStringList(current.getProperties().get(EntityConstants.TYPE))
687 // : new ArrayList<>();
688 // if (!types.containsAll(currentTypes)) {
689 // throw new IllegalArgumentException("Higher-ranked layer " + pid + " contains only types " + types
690 // + ", while it must override all " + currentTypes);
691 // }
692 // }
693 // RankedObject.putIfHigherRank(layersByPid, pid, layer, properties);
694 // for (String type : types)
695 // RankedObject.putIfHigherRank(layersByType, type, layer, properties);
696 // }
697 // }
698
699 public void addLayer(SuiteLayer layer, Map<String, Object> properties) {
700 if (properties.containsKey(Constants.SERVICE_PID)) {
701 String pid = (String) properties.get(Constants.SERVICE_PID);
702 RankedObject.putIfHigherRank(layersByPid, pid, layer, properties);
703 }
704 if (properties.containsKey(EntityConstants.TYPE)) {
705 List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
706 for (String type : types)
707 RankedObject.putIfHigherRank(layersByType, type, layer, properties);
708 }
709 }
710
711 public void removeLayer(SuiteLayer layer, Map<String, Object> properties) {
712 if (properties.containsKey(Constants.SERVICE_PID)) {
713 String pid = (String) properties.get(Constants.SERVICE_PID);
714 if (layersByPid.containsKey(pid)) {
715 if (layersByPid.get(pid).equals(new RankedObject<SuiteLayer>(layer, properties))) {
716 layersByPid.remove(pid);
717 }
718 }
719 }
720 if (properties.containsKey(EntityConstants.TYPE)) {
721 List<String> types = LangUtils.toStringList(properties.get(EntityConstants.TYPE));
722 for (String type : types) {
723 if (layersByType.containsKey(type)) {
724 if (layersByType.get(type).equals(new RankedObject<SuiteLayer>(layer, properties))) {
725 layersByType.remove(type);
726 }
727 }
728 }
729 }
730 }
731
732 public void setCmsUserManager(CmsUserManager cmsUserManager) {
733 this.cmsUserManager = cmsUserManager;
734 }
735
736 // protected Repository getRepository() {
737 // return repository;
738 // }
739 //
740 // public void setRepository(Repository repository) {
741 // this.repository = repository;
742 // }
743
744 protected ContentRepository getContentRepository() {
745 return contentRepository;
746 }
747
748 public void setContentRepository(ContentRepository contentRepository) {
749 this.contentRepository = contentRepository;
750 }
751
752 // public void setJcrContentProvider(JcrContentProvider jcrContentProvider) {
753 // this.jcrContentProvider = jcrContentProvider;
754 // }
755
756 }